`const` 对象的构造函数

j4x*_*j4x 5 c++ constructor arguments constants

考虑这段代码:

\n\n
#include <iostream>\n\nclass test\n{\npublic:\n    test( char *arg )\n    :   _arg( arg )\n    {}  \n    char *_arg;\n};\n\nint main( )\n{\n    char *txt1       = "Text one";  // Ignore this warning.\n    const char *txt2 = "Text two";\n\n    test       t1( txt1 );  // Normal case, nothing new.\n    const test t2( txt2 );  // Since object is const, I\'d like to be able to pass a const argument in.\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

它因错误而爆炸:

\n\n
error: invalid conversion from \xe2\x80\x98const char*\xe2\x80\x99 to \xe2\x80\x98char*\xe2\x80\x99 [-fpermissive]\n   const test t2( txt2 );\n
Run Code Online (Sandbox Code Playgroud)\n\n

然后我尝试添加第二个构造函数来测试编译器是否可以为t2我的const对象选择正确的构造函数:

\n\n
    test( const char *arg )\n    :   _arg( arg )\n    {}  \n
Run Code Online (Sandbox Code Playgroud)\n\n

但错误是:

\n\n
error: invalid conversion from \xe2\x80\x98const char*\xe2\x80\x99 to \xe2\x80\x98char*\xe2\x80\x99 [-fpermissive]\n  : _arg( arg )\n
Run Code Online (Sandbox Code Playgroud)\n\n

因此,将我的对象声明为也const不会生成其字段const

\n\n

如何正确声明我的类构造函数,以便它可以处理const非常量对象创建?

\n

Use*_*ess 5

如何正确声明我的类构造函数,以便它可以处理常量和非常量对象创建?

该对象不在构造const 期间,否则构造函数将无法初始化该对象(因为所有数据成员都将是const)。

因此,构造函数不能是 const 限定的,并且不能将构造函数重载用于const对象。

现在,您可以重载参数,但您的数据成员在构造期间始终具有类型,尽管在 const 限定的 test 实例中使用时char *它被限定为char * const不是)。 const char *

选项有:

  1. 重载参数类型的构造函数,并存储一个char * always。如果你通过了 aconst char *你必须复制它(并且你有责任知道你拥有并且必须释放这个内存)

    在此方案中,您依靠保持指针私有并使用 const 限定的访问器来阻止通过 const 限定的对象更改指针的内容。

    同样,您需要手动执行此操作,因为char * const是 与 不同的类型const char *,因为指向类型的常量性与指针的常量性无关:拥有类的 const 实例只会阻止您改变指针,而不是字符它指向。

  2. 重载构造函数并存储一个const char *always。这可以避免复制,但如果您有时需要更改指向的字符,则显然不起作用

  3. 只需编写不同的可变字符串和不可变字符串类

如果有帮助,请考虑以下内容:

template <typename T> struct test {
    T* p_;
    test(T *p) : p_(p) {}
};
template <typename T> test<T> mktest(T *p) { return {p}; }
Run Code Online (Sandbox Code Playgroud)

并注意

const char *ccp = "immutable characters in a string literal";
char *cp = strdup(ccp);
auto a = mktest(ccp);
auto b = mktest(cp);
Run Code Online (Sandbox Code Playgroud)

给出a类型test<const char>,并且b类型test<char>和 这些类型不相同,不可转换,并且在语言中的相关性并不比test<T>任何其他类型更密切T