这就是我最初的所作所为。
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
答案 0 :(得分:4)
A a4 = 123;
相当于
A a4 = A(123); // The RHS is a temporary A object.
这适用于第一种情况,因为有一个构造函数以A const&
作为参数类型。
如果参数类型为A&
,则不起作用。参数类型为A const&
时,可以使用临时对象,而不是A&
时。
答案 1 :(得分:1)
对于案例A a4 = 123;
,当构造对象“a4”时,语句
A a4 = 123;
被编译器分解为
A a4 = A(123);
在上面的语句中,一个参数构造函数,即A(int)
用于将整数值“123”转换为临时对象&amp;使用复制构造函数将临时对象复制到对象“a4”。 C ++不允许通过非const引用传递临时对象,因为临时对象是不能绑定引用非const的rvalue。
所以,一般来说,如果你没有用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*/}
^~~~