zoukankan      html  css  js  c++  java
  • 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构造函数可能存在相同的代码,但是它们两者之间任何一个调用另外一个都是不合法的。

    总结

    1. Copying函数应该确保复制”对象内的所有成员变量”及”所有base class成分”。
    2. 不要尝试以某个copying函数实现另外一个copying函数。应将共同机能放进第三个函数中,并有两个copying函数共同调用。
  • 相关阅读:
    blktrace 梁斌说
    线索二叉树
    Boost库中文文档
    STL中的equal函数
    HDU3661_assignments_活动分配_贪心
    转:数据结构小结
    HDU2273_车通过路口
    C++之lexicographical_compare
    HDU1671_Phone List
    HDU2277_变色球
  • 原文地址:https://www.cnblogs.com/zhonghuasong/p/7444004.html
Copyright © 2011-2022 走看看