effect C++ 复制对象时勿忘其每一个成分
2017-04-04 13:07
309 查看
copy 函数
设计良好之面向对象系统会将对象的内部封装起来,只留两个函数负责对象拷贝(复制),copy构造函数和co培养assignment 操作符。如果你声明自己的copying函数,意思是告诉编译器你并不喜欢缺省实现中的某些行为。编译器会以一种奇怪的方式回敬:当你的实现代码几乎必然出错却不告诉你。
void logCall(const std::string& funcName);
class Customer{
public :
...
Customer(const Customer&rhs);
Customer& operator=(const Customer &rhs);
...
private:
std::string name;
};
Customer::Customer(const Customer &rhs):name (rhs.name)
{
logCall("Customer copy constructor");
}
Customer &Customer::operator=(const Customer&rhs)
{
logCall("Customer copy assignment operator");
name = rhs.name;
return *this;
}
如果另一个成员变量加入战局
class Date{...};
class Customer{
public:
... //同前
private:
std::string name;
Date lastTransaction;
}
这时既有的copying函数执行的是局部拷贝:复制了name,没有新添加复制的lastTransaction。编译器不会发生怨言。
如果你为class添加一个变量,你必须同时修改copy函数(还有class内所有构造函数以及任何非标准形式的operator=)
一旦发生继承
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的copy构造函数并没有指定的实参传给base class构造函数(也就是说它在它的成员初值列中没有提到Customer),因此PriorityCustomer对象Customer成分会被不带实参之Customer构造函数(即default构造函数)初始化。default构造函数将针对name和lastTransaction执行缺省的初始化动作。
任何时候需要“为derived class 撰写copying函数”的重责大任,必须复制其base class 成分。应该用derived class 的copying函数调用相应的base class函数。 PriorityCustomer::PriorityCustomer(const PriorityCustomer& rhs):Customer(rhs),priority(rhs.priority)
{
logCall("PriorityCustomer copy constructor");
}
PriorityCustomer&PriorityCustomer::operator=(const PriorityCustomer &rhs)
{
logCall("PriorityCustomer copy assignment operator");
Customer::operator=(rhs);
priority = rhs.priority;
return *this;
}当编写一个copying函数,请确保 (1)复制所有local成员变量 (2)调用所有base class 内的适当的copying函数
如果copy函数和copy assignment操作符有相近的代码,消除重复代码的做法是,建立一个新的成员函数给两者调用。这样的函数往往是private而且常被命名为init.
Copying函数应该确保复制“对象内所有成员变量”及“所有base class”成分。
不要尝试以某个copy函数实现另一个copy函数。应该将共同机能放进第三个函数中,并由两个coping函数共同调用。
相关文章推荐
- Effective C++ 条款12:复制对象时勿忘其每一个成分
- Effective C++ Item 12 复制对象时勿忘其每一个成分
- C++ 复制对象时勿忘其每一个成分
- C++之复制对象时勿忘每一个成分(12)---《Effective C++》
- 读书笔记_Effective_C++_条款十二:复制对象时勿忘其每一个成分
- 【effective c++】 条款12:复制对象时勿忘其每一个成分
- 条款12:复制对象时勿忘其每一个成分
- 条款12:复制对象时请勿忘每一个成分
- 12 复制对象时勿忘其每一个成分
- effective c++ 复制对象时勿忘每一个成分
- 条款12:复制对象时勿忘其每一个成分
- Effective C++读书笔记之十二:复制对象时勿忘其每一个成分
- 条款12 复制对象勿忘其每一个成分
- 条款12:复制对象时勿忘其每一个成分(Copy all parts of an object)
- 条款12:复制对象时勿忘其每一个成分
- 复制对象时勿忘其每一个成分(Effective C++_12)
- 条款12:复制对象时勿忘其每一个成分
- 条款12:复制对象时勿忘其每一个成分
- (10)复制对象时勿忘每一个成分
- 条款12:复制对象时勿忘其每一个成分