条款12:复制对象时勿忘其每一个成分
Copy all parts of an object.
不管是什么时候,只要决定为derived class撰写copying函数,就必须小心的将base class中的成风你也完全复制。而因为这些成分往往又是private,无法直接访问,因此:
- 需要让derived class的copying函数调用相应的base class函数。
PriorityCustomer::PriorityCustomer(const PriorityCustomer& rhs)
: Customer(rhs), //调用base class的copy构造函数
Priority(rhs.priority)
{
logCall("PriorityCustomer copy constructor");
}
PriorityCustomer&
PriorityCustomer::operator=(const PriorityCustomer& rhs)
{
logCall("PriorityCustomer copy assignment operator");
Customer::operator=(rhs); //对base class成分进行赋值动作
priority = rhs.priority;
return *this;
}
因此,对于所谓的“赋值每一个成分”,指的就是当编写copying函数时:
- 复制所有的local成员变量。
- 调用所有base classes内的适当的copying函数。
这两个copying函数(即copy构造函数和copy assignment操作符)一般有有着相似的实体,但是
- 令某个copying函数调用另一个copying函数却无法达到目标。
一方面,令copy assignment操作符调用copy构造函数是不合理的,因为这就像试图构造一个已经存在的对象。
另一方面,令copy构造函数去调用copy assignment操作符同样毫无意义。构造函数用来初始化新对象,而assignment操作符则只施加在已经初始化的对象身上。
- 对一个尚未构造好的对象赋值,就像在一个尚未初始化的对象身上做“只对已经初始化对象才有意义”的事情一样。
消除copy代码重复
当copy构造函数和copy assignment操作符拥有相近的代码时,消除代码重复的做法是:
- 建立一个新的成员函数给二者调用。
这样的函数往往是private而且常常被命名为init。利用这样的方法,可以安全地消除copy构造函数和copy assignment操作符之间的代码重复。
最后: