条款12:复制对象的时候不要忘了其每一个部分

  首先要说的是当对一个已经定义了构造函数以及赋值运算符(拷贝)的class增加了成员的时候,一定要记得为这个class重新改写构造函数以及拷贝赋值运算符。

  下一个容易遗忘的点在继承中,看下面的代码:

 1 class Customer
 2 {
 3     public:
 4         //...
 5         Customer(const Customer & rhs):name(rhs){}
 6         Customer & operator=(const Customer & rhs)
 7         {
 8             //...
 9         }
10     private:
11         std::string name;
12 }
13 //再考虑继承的情况。
14 class PriorityCustomer:public Customer
15 {
16     public:
17         //...
18         PriorityCustomer(const PriorityCustomer & rhs)
19         :priority(rhs.priority)
20         {
21             //...
22         }
23         PriorityCustomer & operator=(const PriorityCustomer & rhs)
24         {
25             priority = rhs.priority;
26             return *this;
27         }
28 }

看着好像没错,但是基类事实上没有被构造,应该在derived class中显式的调用base class的构造函数。像下面这样:

 1 class PriorityCustomer:public Customer
 2 {
 3     public:
 4         //...
 5         PriorityCustomer(const PriorityCustomer & rhs)
 6         :priority(rhs.priority)
 7         Customer(rhs)
 8         {
 9             //...
10         }
11         PriorityCustomer & operator=(const PriorityCustomer & rhs)
12         {
13             Customer::operator=(rhs);//这个用法要注意,不然会引起循环递归
14             priority = rhs.priority;
15             return *this;
16         }
17 }

  PS:如果发现copy constructor和copy assignment operator有着相似的代码,消除重复代码的方法是,建立一个新的private成员函数给二者用,一般名字为init()
小结:应该记住的两点是 1. copying函数应该确保复制对象里面你的所有函数包括进行基类的完整构造 2.如果两个copy函数中有相同的部分,

不要尝试用一个区调用另一个,而应该另外声明一个函数处理两个coping函数中公共的部分