复制构造函数中去除const

3

这是我最初所做的事情。

class A
{   public:
    A()         { std::cout << "\ndefault constructor";     }
    A(const A&) { std::cout << "\ncopy constructor";        }
    A(int)      { std::cout << "\nconversion constructor";  }
};

A a0;           // print default constructor
A a1(a0);       // print copy constructor       note : direct initialization
A a2 = a0;      // print copy constructor       note : copy initialization
A a3(123);      // print conversion constructor     note : direct initialization
A a4 = 123;     // print conversion constructor     note : copy initialization (create a temp object from int)

然而,如果将A类略微修改如下(在复制构造函数中去掉const),为什么在最后一行会出现编译错误?谢谢。
class A
{   public:
    A()         { std::cout << "\ndefault constructor";     }
    A(A&)       { std::cout << "\ncopy constructor";        }
    A(int)      { std::cout << "\nconversion constructor";  }
};

A a0;           // print default constructor
A a1(a0);       // print copy constructor       note : direct initialization
A a2 = a0;      // print copy constructor       note : copy initialization
A a3(123);      // print conversion constructor     note : direct initialization
//A a4 = 123;   // compile error

2
临时对象将在创建它的行被销毁,因此编译器认为当您将其作为非const引用传递时,您将对其进行修改(有可能您会通过非const引用进行修改),但是在该范围内已经销毁它,因此修改它是非法的。 - Lorence Hernandez
2个回答

6
A a4 = 123;

等同于

A a4 = A(123); // The RHS is a temporary A object.

对于第一种情况,由于存在一个以 A const& 作为参数类型的构造函数,因此这是可行的。

如果参数类型为 A&,则无法使用临时对象。当参数类型为 A const& 时可以使用临时对象,但参数类型为 A& 时不行。


2
对于代码 A a4 = 123;,当对象“a4”被构造时,编译器将语句分解为A a4 = A(123);。在上述语句中,使用一个参数的构造函数A(int)将整数值“123”转换为临时对象,然后使用复制构造函数将该临时对象复制到对象“a4”中。C++不允许通过非const引用传递临时对象,因为临时对象是rvalue,不能绑定到非const引用。
因此,在一般情况下,如果您没有使用const限定符传递参数,则无法创建const对象的副本。
以下是另一个类似的例子,以便更好地理解:
class Test
{
   /* Class data members */
public:
   Test(Test &t) { /* Copy data members from t*/}
   Test()        { /* Initialize data members */ }
};

Test fun()
{
    cout << "fun() Called\n";
    Test t;
    return t;
}
int main()
{
    Test t1;
    Test t2 = fun();  //compilation error with non-const copy constructor
    return 0;
}

$g++ -o main *.cpp
main.cpp: In function ‘int main()’:
main.cpp:22:18: error: cannot bind non-const lvalue reference of type ‘Test&’ to an rvalue of type ‘Test’
     Test t2 = fun();
               ~~~^~
main.cpp:8:4: note:   initializing argument 1 of ‘Test::Test(Test&)’
    Test(Test &t) { /* Copy data members from t*/}
    ^~~~

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接