设计良好的面向对象系统会将对象的内部封装起来,只留两个函数负责对象拷贝,即copy构造函数与copy assignment操做符。编译器会在必要的时候为类建立coping函数,并说明这些“编译器生成版”的行为:将被拷贝对象的全部成员变量都作一份拷贝。安全
任什么时候候,只要本身实现派生类的copying函数,则必须很当心的复制其基类成分。这些成分每每是private私有的,故没法直接访问它们,所以应该让派送类的coping函数调用相应的基类函数:函数
void logCall(const string& funcName);
class Customer { public:
... Customer(const Customer& rhs); Customer& operator=(const Customer& rhs);
... private: string name; Date lastTranscation; };
class PriorityCustomer : public Customer { public: ... PriorityCustomer(const PriorityCustomer& rhs); PriorityCustomer& operator=(const PriorityCustomer& rhs); ... private: int priority; }; PriorityCustomer ::PriorityCustomer (const PriorityCustomer& rhs) : Customer(rhs), //调用基类的copy构造函数 priority(rhs.priority) { logCall("PriorityCustomer copy constructor"); } PriorityCustomer& PriorityCustomer ::operator = (const PriorityCustomer& rhs) { logCall("PriorityCustomer copy assignment constructor"); Customer::operator=(rhs); //对基类Customer成分进行复制动做 priority = rhs.priority; return *this; }
当编写一个copying函数,确保一、复制全部local成员变量,二、调用全部基类的适当的copying函数。this
注意两个错误用法:一、令copy assignment操做符调用copy构造函数是错误的,由于在这就像试图构造一个已存在的对象。spa
二、令copy构造函数调用copy assignment操做符一样是错误的。构造函数用来出过后对象,而assignment操做符只实行与已初始化的对象身上。对一个还没有构造好的对象赋值,就像在一个还没有初始化的对象身上作“z只对已初始化对象才有意义”的事意义。设计
消除copy构造函数与copy assignment操做符重复代码的作法是:创建一个新的成员函数给二者调用。这样的函数每每是private并且被命名为init。这个策略能够安全消除copy构造函数与copy assignment操做符之间的代码重复。对象
请牢记:blog
一、copying 函数应该确保复制“对象内的全部成员变量”及“全部基类成分”。编译器
二、不要尝试以某个copying函数实现另外一个copying函数。应该将共同机能放进第三个函数中,并由两个copying函数共同调用。string