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构造函数可能存在相同的代码,但是它们两者之间任何一个调用另外一个都是不合法的。
总结
- Copying函数应该确保复制”对象内的所有成员变量”及”所有base class成分”。
 - 不要尝试以某个copying函数实现另外一个copying函数。应将共同机能放进第三个函数中,并有两个copying函数共同调用。
 
Effective C++ 条款12:复制对象时勿忘其每一个成分的更多相关文章
- Effective C++ -----条款12: 复制对象时勿忘其每一个成分
		
Copying函数应该确保复制“对象内的所有成员变量”及“所有base class成分”. 不要尝试以某个copying函数实现另一个copying函数.应该将共同机能放进第三个函数中,并由两个cop ...
 - EC读书笔记系列之7:条款12 复制对象时勿忘其每一个成分
		
记住: ★copying函数应确保复制“对象内的所有成员变量”及“所有base class成分” ★不要尝试以某个copying函数实现另一个copying函数.应该将共同机能放进第三个函数中,并由两 ...
 - Effective C++_笔记_条款12_复制对象时勿忘其每一个成分
		
(整理自Effctive C++,转载请注明.整理者:华科小涛@http://www.cnblogs.com/hust-ghtao/) 编译器会在必要时候为我们的classes创建copying函数, ...
 - EC笔记:第二部分:12、复制对象时勿忘其每一个成分
		
EC笔记:第二部分:12.复制对象时勿忘其每一个成分 1.场景 某些时候,我们不想使用编译器提供的默认拷贝函数(包括拷贝构造函数和赋值运算符),考虑以下类定义: 代码1: class Point{ p ...
 - 条款12:复制对象时勿忘其每一个成分(Copy all parts of an object)
		
NOTE: 1.Copying 函数应该确保复制“对象内的所有成员变量”及“所有base class成分”. 2.不要尝试以某个copying函数实现另一个copying函数.应该将共同机能放进第三个 ...
 - [Effective C++ --012]复制对象时勿忘其每一个成分
		
引言: 在深拷贝和浅拷贝的理解中,我们知道了“拷贝构造函数”一词,并且也了解了它的构成. A(const A& r); // 形式有多种,在这里只列出一个 因此,在值传递的应用场景里,我们可以 ...
 - C++复制对象时勿忘每一部分
		
现看这样一个程序: void logCall(const string& funcname) //标记记录 { cout <<funcname <<endl; } cl ...
 - Effective C++(12)  复制对象时要复制每一个成员
		
问题聚焦: 负责拷贝的两个操作:拷贝构造函数和重载赋值操作符. 一句话总结,确保被拷贝对象的所有成员变量都做一份拷贝. Demo void logCall(const std::string&am ...
 - Effective C++ 条款12
		
复制对象时,勿忘其每个成分 作者在本节条款提醒我们,在多重继承的情况下进行copy或者copy assignment 的operator=的编写时,一定要考虑base 类部分数据的初始化后者复制. 对 ...
 
随机推荐
- Leetcode-Construct Binary Tree from inorder and postorder travesal
			
Given inorder and postorder traversal of a tree, construct the binary tree. Solution: /** * Definiti ...
 - PAT 甲级 1019 General Palindromic Number(简单题)
			
1019. General Palindromic Number (20) 时间限制 400 ms 内存限制 65536 kB 代码长度限制 16000 B 判题程序 Standard 作者 CHEN ...
 - 你不知道的Javascript(上卷)读书笔记之三 ---- 函数作用域与块作用域
			
1. 函数中的作用域 函数作用域的含义是指属于这个函数的全部变量都可以在整个函数范围内使用以及复用 2. 隐藏内部实现 函数经常使用于隐藏”内部实现”,可以把变量和函数包裹在一个函数的作用域中,然后用 ...
 - html常见兼容性问题
			
html常见兼容性问题? 1.双边距BUG float引起的 使用display 2.3像素问题 使用float引起的 使用dislpay:inline -3px 3.超链接hover 点击后失效 ...
 - 用gunicorn+gevent启动Flask项目
			
转自:https://blog.csdn.net/dutsoft/article/details/51452598 Flask,webpy,Django都带着 WSGI server,当然性能都不好, ...
 - jenkins 升级
			
升级Jenkins Jenkins的开发迭代非常快,每周发布一个开发版本,长期支持版每半年更新一次(ps:大版本更新).如此频繁的更新,怎么升级呢? war:下载新版的war文件,替换旧版本war文件 ...
 - swift 值得学习的项目
			
http://www.php100.com/html/it/biancheng/2015/0112/8329.html
 - C# OpenFileDialog 的使用方法
			
OpenFileDialog openFileDialog = new OpenFileDialog(); //打开的文件选择对话框上的标题 openFileDialog.Title = " ...
 - tornado项目下路由系统的使用?
			
路由系统 在web框架中,路由表中的任意一项是一个元组,每个元组包含pattern(模式)和handler(处理器).当httpserver接收到一个http请求,server从接收到的请求中解析出u ...
 - nginx常用
			
1.rewrite return 301 http://example.com$request_uri; rewrite ^ http://example.com permanent; 2.try_f ...