1. 程式人生 > >複製物件時勿忘其每一個成分

複製物件時勿忘其每一個成分

前言:看了好久Effective,但是感覺好多都是看了就忘,現在再看一邊,順便把一些易忘的記錄下來,爭取每天一記。

概念:Copying函式,包括copy constructor;copy assignment operator,對於預設的編譯器生成版,會將被拷貝的物件的所有成員變數都做一份拷貝。

如果你自己宣告一個copying函式,編譯器就會以一種奇怪的方式迴應:當你的實現程式碼幾乎必然出錯時卻不告訴你.(不知道是作者原話還是譯者,感覺挺有意思的)

該條款有兩個需要注意的地方:1複製所有local成員變數2呼叫所有base classes內的copying函式。

第一個地方還好,比較容易理解,下面主要講講第二個->

  1. void logCall(const std::string& funcName);          // make a log entry
  2. class Customer {   
  3. public:   
  4.   ...   
  5.   Customer(const Customer& rhs);   
  6.   Customer& operator=(const Customer& rhs);   
  7.   ...   
  8. private:   
  9.   std::string name;   
  10. };   
  11. Customer::Customer(const Customer& rhs)   
  12. : name(rhs.name)                                 // copy rhs's data
  13. {   
  14.   logCall("Customer copy constructor");   
  15. }   
  16. Customer& Customer::operator=(const Customer& rhs)   
  17. {   
  18.   logCall("Customer copy assignment operator");   
  19.   name = rhs.name;                                  
  20. return *
    this;                                     
  21. }   
  22. class Date { ... };       // for dates in time
  23. class Customer {   
  24. public:   
  25.   ...                     // as before
  26. private:   
  27.   std::string name;   
  28.   Date lastTransaction;   
  29. };   
  30. class PriorityCustomer: public Customer {                  // a derived class
  31. public:   
  32.    ...   
  33.    PriorityCustomer(const PriorityCustomer& rhs);   
  34.    PriorityCustomer& operator=(const PriorityCustomer& rhs);   
  35.    ...   
  36. private:   
  37. int priority;   
  38. };   
  39. PriorityCustomer::PriorityCustomer(const PriorityCustomer& rhs)   
  40. : priority(rhs.priority)   
  41. {   
  42.   logCall("PriorityCustomer copy constructor");   
  43. }   
  44. PriorityCustomer& PriorityCustomer::operator=(const PriorityCustomer& rhs)   
  45. {   
  46.   logCall("PriorityCustomer copy assignment operator");   
  47.   priority = rhs.priority;   
  48. return *this;   
  49. }  

PriorityCustomer類的copying函式好像複製了PriorityCustomer內的每一樣東西,它複製了PriorityCustomer宣告的成員變數,但是其基類Customer成員變數卻沒有被複制(其實應該是沒有按照相應的引數複製,而是使用了這些變數的default建構函式),這一點是尤其需要注意的,尤其是沒有真正寫過類似程式碼時很容易忽視這個問題,正確的寫法是下面這樣的:

  1. PriorityCustomer::PriorityCustomer(const PriorityCustomer& rhs)   
  2. :Customer(rhs),                   // invoke base class copy ctor
  3.  priority(rhs.priority)   
  4. {   
  5.   logCall("PriorityCustomer copy constructor");   
  6. }   
  7. PriorityCustomer& PriorityCustomer::operator=(const PriorityCustomer& rhs)   
  8. {   
  9.   logCall("PriorityCustomer copy assignment operator");   
  10.   Customer::operator=(rhs);           // assign base class parts
  11.   priority = rhs.priority;   
  12. return *this;   
  13. }  

具體內容見Items12。

相關推薦

effective c++條款12:複製物件一個成分

我們都知道,如果需要,編譯器會為我們自動生成copying函式(拷貝構造與copy assignment操作符)。如果我們想覆蓋它們,只需要自己實現copying函式即可; 但是!!!!!!! 編譯器不樂意了o(╥﹏╥)o:好傢伙,既然你不相信我,那你出了某些錯我可別怪我

讀書筆記《Effective c++》 條款12 複製物件一個成分

名詞:   copying函式 = 拷貝建構函式 + 賦值操作符 重點是:當你自己要編寫一個copying函式時,請確保:   a.複製所有local成員變數   b.呼叫所有base class內的適當的copying函式。(拷貝建構函式是在初始化列表呼叫base c

Effective C++:條款12:複製物件一個成分

(一) 一個繼承體系的宣告: class Date {...}; class Customer { public: ... private: string name; Date lastTransaction; }; class PriorityCustomer :

Effective C++ 學記之12 複製物件一個成分

copying函式應該確保複製“物件內的所有成員變數”及“所有base class成分”。 不要嘗試以某個copying函式實現另一個copying函式。應該將共同機能放進第三個函式中,並由兩個copying函式共同呼叫。 這裡說的copying函式指的是“copy建構

Effective C++ 條款12:複製物件一個成分 學習筆記

Effective C++ 條款12:複製物件時勿忘其每一個成分 <textarea readonly="readonly" nam ="code" class="c++"> void logCall(const string& funcName); c

Effective C++讀書筆記之十二:複製物件一個成分

class Date{...}; class Customer { public: ... private: std::string name; Date lastTransaction; }; class PriorityCustomer:public Customer { public: Pri

effect C++ 複製物件一個成分

copy 函式 設計良好之面向物件系統會將物件的內部封裝起來,只留兩個函式負責物件拷貝(複製),copy建構函式和co培養assignment 操作符。 如果你宣告自己的copying函式,意思是告

筆記:條款12: 複製物件一個成分

這是我在閱讀Effective c++中認為比較重要的部分,下面給出了我對這一節的理解,並寫出對應的比較容易理解的程式碼。    如果你宣告自己的copying函式(拷貝構造,拷貝賦值),那麼編譯器在你做出錯誤的動作時不會告訴你,下面定義的copying函式沒有對Def

effective C++ 12_複製物件一個成分 讀書筆記

作者強調了自己定義的copy建構函式和copy assignment操作符容易犯的錯誤: 1. 本來工作很好的,但是後來添加了成員變數,而忘記在copy建構函式和copy assignment操作符裡新增此新新增成員變數的copy,導致以後就工作不正常了。

12複製物件一個成分

設計良好的面向物件系統會將物件的內部封裝起來,只留兩個函式負責物件拷貝。 如果物件增加了一個新的成員,則需要在所有的建構函式,拷貝函式中進行處理。否則會造成區域性拷貝。 如果要為derived class寫coping函式,則必須小心的複製base class成分。 當你

複製物件一個成分

前言:看了好久Effective,但是感覺好多都是看了就忘,現在再看一邊,順便把一些易忘的記錄下來,爭取每天一記。 概念:Copying函式,包括copy constructor;copy assignment operator,對於預設的編譯器生成版,會將被拷貝的物件的所有

《Effective C++》學習筆記條款12 複製物件一個成員

條款12:複製物件時勿忘其每一個成員 還記得條款5中提到編譯器在必要時會為我們提供拷貝建構函式和拷貝賦值函式,它們也許工作的不錯,但有時 候我們需要自己編寫自己的拷貝建構函式和拷貝賦值函式。如果

Effective C++ 條款12 賦值物件一個成分

請記住: 賦值函式應該確保複製物件內的所有成員變數以及所有基類成分; 例如: #include<iostream> using namespace std; class Base { public: Base(){} Base(int x,int y):m

c++複製物件一部分

設計良好之面向物件系統會將物件內部封裝起來,只留兩個函式負責物件拷貝(複製),那便是帶著試切名稱的copy建構函式和copy assignment操作符,稱它們為copying函式,並說明這些“編譯器生成版”的行為:將被拷貝物件的所有成員變數都做一份拷貝。 如果你宣告自己的copying函式

Effective C++——》條款12:複製物件一部分

這句話包含兩部分的意思:第一部分是要考慮到所有成員變數,特別是後加入的,相應的拷貝建構函式和賦值運算子要及時更新;第二部分是在存在繼承時,不要遺忘基類部分的複製。先看第一部分的意思,舉個例子: 1 class SampleClass 2 { 3 private: 4

條款12:複製物件一部分

  複製物件時要把物件的每一部分都賦值到位,尤其在有基類的時候容易遺漏複製   #include<iostream> using namespace std; class Date { public: Date(int d = 1,

條款12:賦值物件忘記一個成分

如果你宣告自己的copying函式,當你你的程式碼出錯時編譯器不會告訴你 void logCall(const string& funcName) { cout << funcName << endl; } cla

條款12 複製物件一個成分

總結: 1. 拷貝函式應該保證拷貝一個物件的所有資料成員以及所有的基類部分。 2. 不要試圖依據一個拷貝函式實現另一個。作為代替,將通用功能放入第三個供雙方呼叫的函式。        設計良好的面向物件系統中,封裝了物件內部,僅留兩個函式用於物件的拷貝:拷貝建構函式和拷

Effective C++讀書筆記---複製物件一個成員

核心點有兩個: 1、如果你堅持自己重寫拷貝建構函式,請記住:編譯器是不會提醒你是否少複製了某一個成員。 2、如果你重寫派生類的拷貝建構函式和拷貝操作符時,請記住:他們不會自動呼叫積累的拷貝建構函式和拷貝操作符。 以下為例子,注意手動呼叫基類的建構函式: class Pri

C++之複製物件一個成分(12)---《Effective C++》

條款12:賦值物件時勿忘其每一個成分 C++中設計良好的物件系統會將物件的內部封裝起來,只留下兩個函式負責物件那個拷貝(賦值),即copy建構函式和copy operator=。 如果我們自己宣告自己的copying函式,則C++的編譯器則不會對我們自己提供