条款12:复制对象时勿忘其每一个部分
設計良好的面向對象系統會將對象的內部封裝起來,只留兩個函數負責對象拷貝,即copy構造函數與copy assignment操作符。編譯器會在必要的時候為類創建coping函數,并說明這些“編譯器生成版”的行為:將被拷貝對象的所有成員變量都做一份拷貝。
任何時候,只要自己實現派生類的copying函數,則必須很小心的復制其基類成分。這些成分往往是private私有的,故無法直接訪問它們,因此應該讓派送類的coping函數調用相應的基類函數:
?void logCall(const string& funcName);class Customer{public:
...Customer(const Customer& rhs);Customer& operator=(const Customer& rhs);
...private:string name;Date lastTranscation;};
class PriorityCustomer : public Customer{public:...PriorityCustomer(const PriorityCustomer& rhs);PriorityCustomer& operator=(const PriorityCustomer& rhs);...private:int priority;};PriorityCustomer ::PriorityCustomer (const PriorityCustomer& rhs) : Customer(rhs), //調用基類的copy構造函數priority(rhs.priority){logCall("PriorityCustomer copy constructor");}PriorityCustomer& PriorityCustomer ::operator = (const PriorityCustomer& rhs) {logCall("PriorityCustomer copy assignment constructor");Customer::operator=(rhs); //對基類Customer成分進行復制動作priority = rhs.priority;return *this;}
當編寫一個copying函數,確保1、復制所有local成員變量,2、調用所有基類的適當的copying函數。
注意兩個錯誤用法:1、令copy assignment操作符調用copy構造函數是錯誤的,因為在這就像試圖構造一個已存在的對象。
2、令copy構造函數調用copy assignment操作符同樣是錯誤的。構造函數用來出事后對象,而assignment操作符只實行與已初始化的對象身上。對一個尚未構造好的對象賦值,就像在一個尚未初始化的對象身上做“z只對已初始化對象才有意義”的事意義。
消除copy構造函數與copy assignment操作符重復代碼的做法是:建立一個新的成員函數給兩者調用。這樣的函數往往是private而且被命名為init。這個策略可以安全消除copy構造函數與copy assignment操作符之間的代碼重復。
請牢記:
1、copying 函數應該確保復制“對象內的所有成員變量”及“所有基類成分”。
2、不要嘗試以某個copying函數實現另一個copying函數。應該將共同機能放進第三個函數中,并由兩個copying函數共同調用。
轉載于:https://www.cnblogs.com/lwenwen/p/3468569.html
總結
以上是生活随笔為你收集整理的条款12:复制对象时勿忘其每一个部分的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: JavaWeb -- Struts1 多
- 下一篇: 【转载】dotnet 线程同步