2012-06-07 83 views
2

例如在下面的代碼:編譯器何時在C++中創建複製構造函數?

class HowMany { 
    static int objectCount; 
    public: 
     HowMany() { 
      objectCount++; 
     } 
     static void print(const string& msg = "") { 
      if(msg.size() != 0) 
       cout << msg << ": "; 

      cout << "objectCount = " << objectCount << endl; 
     } 
     ~HowMany() { 
      objectCount--; 
      print("~HowMany()"); 
     } 
}; 

int HowMany::objectCount = 0; 

// Pass and return BY VALUE: 
HowMany f(HowMany x) { 
    x.print("x argument inside f()"); 
    return x; 
} 

int main() { 
    HowMany h; 
    HowMany::print("after construction of h"); 
    HowMany h2 = f(h); 
    HowMany::print("after call to f()"); 
} 

爲什麼編譯器不會自動爲類的howmany創建拷貝構造函數,逐位拷貝發生時調用至f(h)發生地方?

在什麼情況下,編譯器創建默認的複製構造函數,以及在什麼情況下它不創建?

它給輸出爲:

施工小時後:objectCount = 1

X內˚F()的參數:objectCount = 1周

〜的howmany():objectCount = 0

呼叫f()後:objectCount = 0

〜HowMany():objectCount = -1

〜的howmany():objectCount = -2

許多許多由於事先

+0

你怎麼知道itd不會創建? (順便說一句,你的頭銜說「有」,你的問題說「不」),首先解決。) – Nawaz

+0

檢查它的輸出。我問,什麼時候它自動創建,什麼時候不創建。 – Luv

+0

輸出在哪裏?你希望我們編譯並執行你的代碼來查看輸出結果嗎?然後回答它? – Nawaz

回答

9

在C++ 98和C++ 03編譯器總是產生一個複製構造,其執行成員逐一除非你明確指出你自己寫了。

這就是在你的代碼中發生的事情:編譯器生成的拷貝構造函數沒有做任何特別的事情 - 特別是它不會增加objectCount - 所以最終得到一個負數的對象數(所有拷貝的對象都沒有不增加櫃檯,但他們確實減少了)。

爲了得到你所期望的結果,你會寫是這樣的:

HowMany(const HowMany &) { 
     objectCount++; 
} 

  1. 即使你寫的拷貝構造函數的原型,但不要不創建默認的拷貝構造函數實現它,並/或將其標記爲私有 - 實際上,這就是您如何創建一個不可複製的類。 C++ 11還支持一種特殊的語法來告訴編譯器不要生成任何拷貝構造函數。
+0

值得一提的是,在這個類中實現一個拷貝構造函數看起來像'HowMany(const HowMany&objectToCopy){/ *在這裏拷貝到* /}'。 –

+0

這在C++ 11中仍然如此嗎?除非我自己編寫,否則編譯器是否會生成複製構造函數? –

+1

@JonathanMee:是的,它應該基本相同,除了一些額外的與移動構造函數的交互(如果提供自定義移動構造函數,IIRC將移除默認的拷貝構造函數)。 –

0

對於每個對象編譯器都應該創建拷貝構造函數,這裏也拷貝爲所有對象h,x和h2創建的構造函數。但是對於h對象拷貝構造函數是沒有必要的。接下來你要調用一個函數f,輸入參數爲h。這裏複製構造函數調用並將h中的內容複製到x對象中。對於下一個對象h2也是同樣的東西(這裏也複製構造函數調用並將x複製到h2)。因爲這個原因,只有objectcount不會遞增。謝謝。