• EC读书笔记系列之7:条款12 复制对象时勿忘其每一个成分


    记住:

    ★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之间的代码重复。

  • 相关阅读:
    浅谈Charles —— 青花瓷
    jdbc
    装饰者模式
    java可变参数
    简单日历
    DVD管理系统
    图片拷贝
    时间输出
    java基础小知识
    jQuery HTML
  • 原文地址:https://www.cnblogs.com/hansonwang99/p/4935912.html
Copyright © 2020-2023  润新知