Effective C++ 条款12:复制对象时勿忘其每一个成分

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.anme) {
	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函数中没有对其进行赋值,编译器也不会报错,这个时候可能不是我们想要的结果。

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继承了Customer,而那些成员变量却未被赋值。但在构造PriorityCustomer之前,肯定调用了Customer构造函数(即default构造函数——必定有一个否则无法通过编译)初始化。default构造函数将指针对name和lastTransaction执行缺省的初始化动作。
任何时候只要你承担起"为derived class 撰写copying函数"的重大责任,必须很小心地也复制其base class成分。那些成分往往是private,所以你无法直接访问它们,你应该让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);		// 对base class成分进行赋值动作
	priority = rhs.priority;
	return *this;
}

copy assignment和copy构造函数可能存在相同的代码,但是它们两者之间任何一个调用另外一个都是不合法的。

总结

  1. Copying函数应该确保复制”对象内的所有成员变量”及”所有base class成分”。
  2. 不要尝试以某个copying函数实现另外一个copying函数。应将共同机能放进第三个函数中,并有两个copying函数共同调用。
posted @ 2017-08-28 15:21  清水汪汪  阅读(309)  评论(0编辑  收藏  举报