EC读书笔记系列之7:条款12 复制对象时勿忘其每一个成分
记住:
★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之间的代码重复。
EC读书笔记系列之7:条款12 复制对象时勿忘其每一个成分的更多相关文章
- Effective C++ -----条款12: 复制对象时勿忘其每一个成分
Copying函数应该确保复制“对象内的所有成员变量”及“所有base class成分”. 不要尝试以某个copying函数实现另一个copying函数.应该将共同机能放进第三个函数中,并由两个cop ...
- Effective C++_笔记_条款12_复制对象时勿忘其每一个成分
(整理自Effctive C++,转载请注明.整理者:华科小涛@http://www.cnblogs.com/hust-ghtao/) 编译器会在必要时候为我们的classes创建copying函数, ...
- EC笔记:第二部分:12、复制对象时勿忘其每一个成分
EC笔记:第二部分:12.复制对象时勿忘其每一个成分 1.场景 某些时候,我们不想使用编译器提供的默认拷贝函数(包括拷贝构造函数和赋值运算符),考虑以下类定义: 代码1: class Point{ p ...
- Effective C++ 条款12:复制对象时勿忘其每一个成分
void logCall(const std::string& funcName); class Customer { public: ... Customer (const Customer ...
- 条款12:复制对象时勿忘其每一个成分(Copy all parts of an object)
NOTE: 1.Copying 函数应该确保复制“对象内的所有成员变量”及“所有base class成分”. 2.不要尝试以某个copying函数实现另一个copying函数.应该将共同机能放进第三个 ...
- EC读书笔记系列之17:条款41、42、43、44、45、46
条款41 了解隐式接口与编译器多态 记住: ★classes和templates都支持接口和多态 ★对classes而言接口是显式的(explicit),以函数签名为中心.多态则是通过virtual函 ...
- EC读书笔记系列之11:条款20、21
条款20 宁以pass-by-reference-to-const替换pass-by-value 记住: ★尽量以pass-by-reference-to-const替换pass-by-value.前 ...
- EC读书笔记系列之8:条款13、14、15
条款13 以对象管理资源 记住: ★为防止资源泄漏,请使用RAII对象,它们在构造函数中获得资源并在析构函数中释放 ★两个常被使用的RAII classes分别是tr1::shared_ptr和aut ...
- EC读书笔记系列之6:条款11 在operator=中处理自我赋值
记住: ★确保当对象自我赋值时operator=有良好行为.有三种方法:比较“来源对象”和“目标对象”的地址.精心周到的语句顺序.以及copy-and-swap技术 ★确定任何函数若操作一个以上对象, ...
随机推荐
- 查询本天气预报Web Services支持的国内外城市或地区信息
原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信息和本声明.否则将追究法律责任.http://zhangkui.blog.51cto.com/1796259/497324 本文 ...
- JS正则表达式大全【转】
正则表达式中的特殊字符 字符 含意 \ 做为转意,即通常在"\"后面的字符不按原来意义解释,如/b/匹配字符"b",当b前面加了反斜杆后/\b/,转意为匹配一个 ...
- last reboot
last reboot是一个linux命令,查看上次重启时间等相关信息
- 《JavaScript 闯关记》
为何写作此课程 stone 主要负责基于 Web 的企业内部管理系统的开发,虽然能够熟练地使用 JavaScript,但随着对 JavaScript 的理解越来越深,才发现自己尚未掌握其精髓. 201 ...
- 对于deferred的一点点理解
deferred对象,是一个异步队列.能够实现异步代码调用,从而解决代码执行顺序的问题. 它提供了一下主要方法: jQuery.Deferred() 一个构造函数,返回一个链式实用对象方法来注册多个回 ...
- Linux下进程的文件访问权限
本文转自 http://blog.csdn.net/chosen0ne/article/details/10581883 对进程校验文件访问权限包括两个部分,一是确定进程的角色(属于哪个用户或者组), ...
- Win32汇编开始 Hello Asm
今天开始学习Win32汇编 因为自己很多都是Windows方面 所以 接触一下Win32汇编 . ;.386指令集 .model flat,stdcall ;工作模式 option casemap:n ...
- C语言_double_精度的谜团
double-long long 和0的比较,double和double之间比较
- BZOJ 3307: 雨天的尾巴( LCA + 线段树合并 )
路径(x, y) +z : u处+z, v处+z, lca(u,v)处-z, fa(lca)处-z, 然后dfs一遍, 用线段树合并. O(M log M + M log N). 复杂度看起来不高, ...
- 判断mysqli函数里的sql语句是否有错和影响行数
<?php $mysqli=@new mysqli("localhost", "root", "123456", "xsph ...