C++ 中的默认赋值运算符和引用
我们在这里讨论了动态分配资源的赋值运算符重载。在本文中,我们讨论了当我们不编写自己的赋值运算符时,编译器会自己创建一个赋值运算符来进行浅拷贝,从而导致问题。当类有指针作为成员字段时,浅拷贝和深拷贝之间的区别变得明显。但是,不使用指针时没有区别。当我们的类中有引用并且没有用户定义的赋值运算符时会发生什么。
例如,预测以下程序的输出,
CPP
// CPP program to demonstrate references in a class and
// there is no user defined assignment operator
#include
using namespace std;
class Test {
int x;
int& ref;
public:
Test(int i)
: x(i)
, ref(x)
{
}
void print() { cout << ref; }
void setX(int i) { x = i; }
};
// Driver Code
int main()
{
Test t1(10);
Test t2(20);
t2 = t1;
t1.setX(40);
t2.print();
return 0;
}
CPP
// CPP Program to demonstrate assignment operator
#include
using namespace std;
class Test {
int x;
int& ref;
public:
Test(int i)
: x(i)
, ref(x)
{
}
void print() { cout << ref; }
void setX(int i) { x = i; }
Test& operator=(const Test& t)
{
x = t.x;
return *this;
}
};
int main()
{
Test t1(10);
Test t2(20);
t2 = t1;
t1.setX(40);
t2.print();
return 0;
}
输出:
Compiler Error: non-static reference member 'int& Test::ref',
can't use default assignment operator
在以下情况下,编译器不会创建默认赋值运算符:
1.类具有const类型或引用类型的非静态数据成员。
2.类有一个类型的非静态数据成员,该类型具有不可访问的复制赋值运算符。
3.类派生自具有不可访问的复制赋值运算符的基类。
当上述任一条件为真时,用户必须定义赋值运算符。例如,如果我们在上面的代码中添加一个赋值运算符,代码可以正常工作,没有任何错误。
CPP
// CPP Program to demonstrate assignment operator
#include
using namespace std;
class Test {
int x;
int& ref;
public:
Test(int i)
: x(i)
, ref(x)
{
}
void print() { cout << ref; }
void setX(int i) { x = i; }
Test& operator=(const Test& t)
{
x = t.x;
return *this;
}
};
int main()
{
Test t1(10);
Test t2(20);
t2 = t1;
t1.setX(40);
t2.print();
return 0;
}
输出
10