记住:

★copying函数应确保复制“对象内的所有成员变量”及“所有base class成分

★不要尝试以某个copying函数实现另一个copying函数。应该将共同机能放进第三个函数中,并由两个copying函数共同调用

---------------------------------------------------------------

copying函数包括:copy constructor和copy assignment operator

引出问题的例子:

  1. class Customer {
  2.  
  3. public:
  4. ...
  5. Customer( const Customer &rhs );
  6. Customer& operator=( const Customer &rhs );
  7. ...
  8. private:
  9. std::string name;
  10. Date lastTransaction;
  11. };

当发生继承时,有一个潜藏危机:

  1. class PriorityCustomer : public Customer {
  2.  
  3. public:
  4. ...
  5. PriorityCustomer( const PriorityCustomer &rhs );
  6. PriorityCustomer& operator=( const PriorityCustomer &rhs );
  7. ...
  8. private:
  9. int priority; //派生类独有的成员
  10. };
  11.  
  12. PriorityCustomer::PriorityCustomer( const PriorityCustomer &rhs ):priority( rhs.priority ) {
  13.  
  14. logCall( "PriorityCustomer copy constructor" );
  15. }
  16.  
  17. PriorityCustomer& PriorityCustomer::operator=( const PriorityCustomer &rhs ) {
  18.  
  19. logCall( "PriorityCustomer copy assignment operator" );
  20. priority = rhs.priority;
  21. return *this;
  22. }

PriorityCustomer的copying函数看起来好像赋值了PriorityCustomer内的每个东西,但实际每个PriorityCustomer还内含有它所继承的基类:Customer成员变量复件,而那些成员变量却未被复制,这种情况特别容易忽视!!!

改进如下:

  1. PriorityCustomer::PriorityCustomer( const PriorityCustomer &rhs )
  2. :Customer( rhs ), //不要忘了调用base class的copy constructor!!!
  3. priority( rhs.priority ) {
  4.  
  5. logCall( "PriorityCustomer copy constructor" );
  6. }
  7.  
  8. PriorityCustomer& PriorityCustomer::operator=( const PriorityCustomer &rhs ) {
  9.  
  10. logCall( "PriorityCustomer copy assignment operator" );
  11. Customer::operator=( rhs ); //不要忘了对base class成分进行赋值操作
  12. priority = rhs.priority;
  13. return *this;
  14. }

本条款所说的“复制每一个成分”,意指当你编写一个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. H面试程序(11): 判断字符串是否包含子串问题

    题目描述:                        如字符串str1为''abcdef'''                       字符串str2为'' bc''; 则字符串str1中含有 ...

  2. HDoj-2072-字数

    字数 Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submiss ...

  3. Swift中的集合类型

    一.引子: 在2014年10月TIOBE编程语言排行榜中,Swift位居第18位,从2014WWDC发布会首次公布至今不到半年时间,swift一直受到编程人 员的追捧,其热衷程度并不亚于当红巨星Tay ...

  4. 移动端H5页面之iphone6的适配

    iphone6 及 iphone 6 plus 已经出来一段时间了.很多移动端网站,以前写死body 为320px的,现在估计也忙着做适配了. 大屏幕手机其实一直有,只是以前大家没怎么重视,移动端的H ...

  5. T-SQL触发器

    触发器 对表进行增删改操作时,自动执行的一个操作.当操作一个表的同时,需要进行其它关联操作的时候,就可以用到触发器. 比如:下订单时,创建中的商品数量需要减少 比如:退票时,总的票量要增加 属于DDL ...

  6. 用于Lucene的各中文分词比较

    对几种中文分析器,从分词准确性和效率两方面进行比较.分析器依次为:StandardAnalyzer.ChineseAnalyzer.CJKAnalyzer.IK_CAnalyzer.MIK_CAnal ...

  7. ASP.NET怎么防止多次点击提交按钮重复提交

    今天做一个系统,由于服务器有点慢,所以常会被点击两次或三次,提交的数据就是多次了.所以要让按钮点击后,不能再次点击. 对于一个按钮,要让变成恢色的,只要this.disabled=true就可以了,可 ...

  8. ora-00600笔记

    一. ORA-600 概述 Errorsof the form ORA-600 are called internal errors. This section clarifies themisund ...

  9. OC-类

    1.关于头文件 #include <stdio.h>     #import <Foundation/Foundation.h> 区别:#import指令导入更快更有效率.#i ...

  10. jquery 获取select选中的值

    获取选中的名称:$("#selectPinType option:selected").text(); 获取选中的值:$("#selectPinType option:s ...