編譯器合成複製建構函式

來源:互聯網
上載者:User

標籤:c++

定義:

      只有單個形參,該形參是對本類類型對象的引用(常用const修飾),這樣的建構函式成為複製建構函式。

使用方式:

(1)顯示使用----用一個同類型的對象初始化該對象時;

(2)隱式使用----將該類型的對象傳遞給函數或從函數返回該類型對象時。

三種類型的複製建構函式:

*bitwise copy constructor :逐位複製-----預設

*合成的 copy constructor :編譯器合成----執行逐個成員初始化(memberwise initialize),只完成必要的工作,

*自訂的copy constructor:由類設計者定義------因為有些類必須對複製對象加以控制,如資料成員是指標的情況或者資料成員表示在建構函式中分配的其他資源,或類在建立新對象時必須要做一些特定工作,這時候就需要定義自己的複製建構函式。

關於淺拷貝與深拷貝:

淺拷貝:shllow copy= bitwise copy-----逐位(位元組)拷貝(預設情況)

例子:

[cpp] view plaincopyprint?
  1. <span style="font-size:24px;">class Base{  
  2. public:  
  3.          int a;  
  4.          char ch;  
  5.          char* str;  
  6. }  
  7. Base b1;  
  8. b1.a=15;  
  9. b1.ch=‘c‘;  
  10. b1.str="string";  
  11. b2=b2;</span>  

現在看看b1和b2的記憶體布局(不考慮對齊):


可以看到:b1.str和b2.str指向了同一記憶體空間,即當一方撤銷時,另一方將受到影響,故應極力避免這種情況-----深度拷貝

深度拷貝:deep copy = memberwise copy-----挨個成員拷貝

再看b1和b2的記憶體布局:


此時b1.str和b2.str指向了不同的記憶體空間,但內容(string)還是一樣的。

由於編譯器預設是bitwise copy semantics

即如果類中沒有明確定義或被編譯器合成copy constructor(即memberwise copy),則預設使用bitwise copy形式。

註:以上編譯器合成copy constructor和bitwise copy constructor兩種情況,均不需要類設計的參與!


那麼什麼 情況下bitwise copy semantics會失效呢?

有四種情況:

(1)當class內含一個class member object ,而後者的class聲明有一個copy constructor 時----被class設計者明確聲明或被編譯器合成-------遞迴調用;

(2)當class繼承自一個base class,而後者存在一個copy constructor時-----被class設計者明確聲明或被編譯器合成-------遞迴調用;

(3)當class聲明了一個或多個virtual functions時-------因為此時要考慮類對象中的虛函數表指標vptr的值。

當在同層對象之間進行初始化時,bitwise copy已經夠用了(為簡化,此時不考慮含有指標成員的情況);

例子:

[cpp] view plaincopyprint?
  1. <span style="font-size:18px;">class ZooAnimal{  
  2. public:  
  3.       ZooAnimal();  
  4.       virtual ~ZooAnimal();  
  5.         
  6.       virtual void animate();  
  7.        virtual void draw();  
  8. .....  
  9. };  
  10. class Bear : public ZooAnimal{  
  11. public:  
  12.       Bear();  
  13.       void animate();  
  14.       void draw();  
  15.       virtual void dance();  
  16. ......  
  17. };  
  18. Bear yogi;  
  19. Bear winnie = yogi;  //bitwise copy</span>  

其記憶體布局如下:

但是如果存在:當一個base class object以其derived class 的object內容做初始化操作時,此時若bitwise copy顯然會出錯,因為其vptr將指向不同的虛表,故此時編譯器需要合成copy constrctor,以保證vptr複製操作的安全。合成出來的base class object copy constructor會明確是定object的vptr指向base class object 的vitrual table,而不是直接從右手邊的class object 中將其vptr現值拷貝過來。

如:

[cpp] view plaincopyprint?
  1. <span style="font-size:18px;">void draw(const ZooAnimal& zoey )  
  2. {  
  3.      zoey.draw();  
  4. }  
  5. ZooAnimal franny = yogi;//發生切割(sliced)行為  
  6. draw(yogi); //調用Bear::draw();  
  7. draw(franny); //調用ZooAnimal::draw()</span><span style="font-size:16px;">  
  8. </span>  

其記憶體布局如下(此時由編譯器合成copy constructor):


(4)當class派生自一個繼承串鏈時,其中有一個或多個virtual base classes時。

編譯器合成複製建構函式

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.