http://coliru.stacked-crooked.com/a/8356f09dff0c9308
#include <iostream>
struct A
{
A(int& var) : r(var) {}
int &r;
};
int main(int argc, char** argv)
{
int x = 23;
A a1(x); // why this line is fine?
A a2 = a1; // why this line is fine?
a2 = a1; // error: use of deleted function 'A& A::operator=(const A&)'
// note: 'A& A::operator=(const A&)' is implicitly deleted because the default definition would be ill-formed:
// error: non-static reference member 'int& A::r', can't use default assignment operator
return 0;
}
删除默认分配运算符。为什么仍然保留默认的拷贝构造函数?
答案 0 :(得分:4)
A a1(x);
很好,因为它构建了一个A
的实例,其引用(x
被转换为引用,并且构造函数A(int&)
被调用)
A a2 = a1;
也很好,因为它仍然是 构造。实际上是复制结构。 可以用另一个引用来初始化引用。
例如:
int a = 1;
int& b = a;
int& c = b;
没关系,因为这是所有构造(Demo)
但是,您不能分配引用,这是a2 = a1
将通过编译器生成的副本赋值运算符尝试执行的操作。但是,编译器认识到这一点并且没有生成这样的运算符。由于运算符不存在,因此出现编译错误。
答案 1 :(得分:0)
分配和构造是两种不同的野兽。
默认赋值运算符不能存在,因为无法将引用分配给(如果您尝试使用“user-land”代码,则实际上将分配给referant)。
默认的复制构造函数没有这样的问题,因为我们可以创建引用就好了。
答案 2 :(得分:0)
复制赋值运算符和复制构造函数是两个不同的东西。它不保证当复制赋值运算符存在时,复制构造函数也存在,但它们遵循自己的规则。
从copy assignment operator,它提到:
如果T具有引用类型的非静态数据成员,则类T的默认复制赋值运算符被定义为“已删除”。那是这样的:D
对于Copy构造函数,它有自己的规则来决定是否删除,例如,如果类中存在非静态右值引用数据成员,则默认的复制构造函数将被定义为“已删除”。您可以访问docs了解更多信息。