记住:
★copying函数应确保复制“对象内的所有成员变量”及“所有base class成分”
★不要尝试以某个copying函数实现另一个copying函数。应该将共同机能放进第三个函数中,并由两个copying函数共同调用
---------------------------------------------------------------
copying函数包括:copy constructor和copy assignment operator
引出问题的例子:
class Customer { public:
...
Customer( const Customer &rhs );
Customer& operator=( const Customer &rhs );
...
private:
std::string name;
Date lastTransaction;
};
当发生继承时,有一个潜藏危机:
class PriorityCustomer : public Customer { public:
...
PriorityCustomer( const PriorityCustomer &rhs );
PriorityCustomer& operator=( const PriorityCustomer &rhs );
...
private:
int priority; //派生类独有的成员
}; PriorityCustomer::PriorityCustomer( const PriorityCustomer &rhs ):priority( rhs.priority ) { logCall( "PriorityCustomer copy constructor" );
} PriorityCustomer& PriorityCustomer::operator=( const PriorityCustomer &rhs ) { logCall( "PriorityCustomer copy assignment operator" );
priority = rhs.priority;
return *this;
}
PriorityCustomer的copying函数看起来好像赋值了PriorityCustomer内的每个东西,但实际每个PriorityCustomer还内含有它所继承的基类:Customer成员变量复件,而那些成员变量却未被复制,这种情况特别容易忽视!!!
改进如下:
PriorityCustomer::PriorityCustomer( const PriorityCustomer &rhs )
:Customer( rhs ), //不要忘了调用base class的copy constructor!!!
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函数,应确保:
(1)复制所有local成员变量;
(2)调用所有base classes内的适当的copying函数
若发现copy constructor和copy assignment operator有相近的代码,为了消除重复代码,应建立一个新的成员函数给两者调用(此函数往往是private且常被命名为init)。此策略可以安全消除copy constructor和copy assignment operator之间的代码重复。