C++ 复制构造函数和赋值运算符函数

时间:2021-07-04 19:26:00
 1 class A
2 {
3 public:
4 A(int x) : _x(x){}
5 ~A(){}
6 public:
7 int _x; //方便测试改为public
8 public:
9 A(const A& a){_x = a._x;}
10 A &operator=(const A& a);
11 };
12
13 A &A::operator=(const A &a)
14 {
15 if(this == &a) return *this;
16
17 _x = a._x;
18
19 return *this;
20 }

先看上面一段简单代码,写的很简单的浅拷贝,之前对于复制构造函数存在相当多的不理解。

(1)不理解为什么参数要写成引用,后来看了剑指offer后,上面说如果不写成引用,调用A的复制构造函数时参数会copy,此时会调用自己本身的复制构造函数,所以一层层的调用,直到栈溢出。

(2)赋值运算符函数为什么要返回实例自身的引用,主要是为了支持如下功能:

A a(10);

A b(20);

A c(30);

a = b = c;

如果返回的是void,就无法支持a = b = c,至于为什么返回的是引用,请看下面的式子:

如果赋值运算符函数为这样: A operator=(const A& a);

(a = b) = c;

结果a._x 等于多少?  结果是20,而不是30,因为返回的不是引用,只是一个临时的对象,修改的也是那个临时对象的值,而不是对象a的 值。

(3)赋值运算符函数内部为什么是const 并且是引用,因为赋值运算符函数不会改变传入实例的状态,因此需要加上const,至于为什么是引用,则是因为如果不是引用,参数会被复制一份副本,从而会调用一次复制构造函数,会增加函数调用的开销。