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,至于为什么是引用,则是因为如果不是引用,参数会被复制一份副本,从而会调用一次复制构造函数,会增加函数调用的开销。

posted on 2018-03-14 23:25  gtxvs  阅读(153)  评论(0编辑  收藏  举报