记住:

★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 复制对象时勿忘其每一个成分的更多相关文章

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

    Copying函数应该确保复制“对象内的所有成员变量”及“所有base class成分”. 不要尝试以某个copying函数实现另一个copying函数.应该将共同机能放进第三个函数中,并由两个cop ...

  2. Effective C++_笔记_条款12_复制对象时勿忘其每一个成分

    (整理自Effctive C++,转载请注明.整理者:华科小涛@http://www.cnblogs.com/hust-ghtao/) 编译器会在必要时候为我们的classes创建copying函数, ...

  3. EC笔记:第二部分:12、复制对象时勿忘其每一个成分

    EC笔记:第二部分:12.复制对象时勿忘其每一个成分 1.场景 某些时候,我们不想使用编译器提供的默认拷贝函数(包括拷贝构造函数和赋值运算符),考虑以下类定义: 代码1: class Point{ p ...

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

    void logCall(const std::string& funcName); class Customer { public: ... Customer (const Customer ...

  5. 条款12:复制对象时勿忘其每一个成分(Copy all parts of an object)

    NOTE: 1.Copying 函数应该确保复制“对象内的所有成员变量”及“所有base class成分”. 2.不要尝试以某个copying函数实现另一个copying函数.应该将共同机能放进第三个 ...

  6. EC读书笔记系列之17:条款41、42、43、44、45、46

    条款41 了解隐式接口与编译器多态 记住: ★classes和templates都支持接口和多态 ★对classes而言接口是显式的(explicit),以函数签名为中心.多态则是通过virtual函 ...

  7. EC读书笔记系列之11:条款20、21

    条款20 宁以pass-by-reference-to-const替换pass-by-value 记住: ★尽量以pass-by-reference-to-const替换pass-by-value.前 ...

  8. EC读书笔记系列之8:条款13、14、15

    条款13 以对象管理资源 记住: ★为防止资源泄漏,请使用RAII对象,它们在构造函数中获得资源并在析构函数中释放 ★两个常被使用的RAII classes分别是tr1::shared_ptr和aut ...

  9. EC读书笔记系列之6:条款11 在operator=中处理自我赋值

    记住: ★确保当对象自我赋值时operator=有良好行为.有三种方法:比较“来源对象”和“目标对象”的地址.精心周到的语句顺序.以及copy-and-swap技术 ★确定任何函数若操作一个以上对象, ...

随机推荐

  1. HTML5图片预览

    两种方式实现 URL FileReader <!DOCTYPE HTML><html>    <head>    <meta charset="ut ...

  2. 2D转换

    转换是CSS3 中具有颠覆性的特征之一,可以实现元素的位移.旋转.变形.缩放,甚至支持矩阵方式,配合即将学习的过渡和动画知识,可以取代大量之前只能靠Flash才可以实现的效果.在css3 当中,通过t ...

  3. .net通用权限框架B/S(一)

    一直做软件实施,用过一些二次开发平台,最近看了一些大神写的框架,于是参考写了一个B/S通用权限框架,项目使用MVC4+EF5+EASYUI(.net framework4),开发环境vs2010+sq ...

  4. Android开发环境的搭建之(三)虚拟设备AVD的创建

    选择AVD Manager选项,启动创建AVD向导.根据开发要求创建制定配置的虚拟设备. 设置屏幕大小为17寸,480X800 设置系统映像为API17,X86. 设置AVD Name为MyPhone ...

  5. WebView的基本使用

    ---恢复内容开始--- 一.实例化WebView 通过xml实例化 xml <WebView android:id="@+id/webview" android:layou ...

  6. VS2010中查询替换使用

    MSDN:http://msdn.microsoft.com/zh-cn/library/afy96z92.aspx 例子:

  7. Unicode解码、URL编码/解码

    + (NSString *) stringByReplaceUnicode:(NSString *)string { NSMutableString *convertedString = [strin ...

  8. Win手机安卓程序初体验

    老大说快看博客园,Windows手机可以装安卓程序了. 啊,真的么?可以在我的撸妹1520上愉快的玩COC了么?我还可以愉快的看小说,不对,是听小说,哈哈,安卓君的三千万程序兵,等着老夫来一一临幸你们 ...

  9. 响应式web之媒体查询(一)

    HTML4和css2目前支持为不用的媒体类型设定专有的样式,如,一个页面在屏幕上时使用无衬线字体,而在打印时使用衬线字体.screen和print是两种已定义的媒体类型.媒体查询让样式表有更强的针对性 ...

  10. java synchronized使用

    java synchronized 基本上,所有并发的模式在解决线程冲突问题的时候,都是采用序列化共享资源的方案.这意味着在给定时刻只允许一个任务访问该资源.这个一般通过在代码上加一条锁语句实现,因为 ...