2012-06-01 129 views
1

根據「內部C++對象模型」,只有在以下四個條件中至少有一個條件爲真時,纔會生成複製構造函數(如果程序員未聲明):什麼時候在C++中生成默認構造函數

  1. 當類包含一個複製構造函數存在的類的成員對象時(或者由類設計器顯式聲明,就像前一個String類的情況一樣,或者由編譯器合成) Word類)

  2. 當這個類是從一個複製構造函數存在的基類派生的(同樣,明確地聲明或合成的)

  3. 當類聲明一個或多個虛擬功能

  4. 當類是從其中一個或多個基類是虛擬繼承鏈衍生

這意味着如果我只有構造函數的類,那麼複製構造函數將不會被編譯器提供。

讓我們舉個例子:

class test 
{ 
    test(){} 
}; 
int main() 
{ 
    test obj1;  //statement 1 
    test obj2(obj1); //statement 2 
} 

上面的代碼工作正常。現在問題來了,當我在類測試中添加以下行:

test(const test& rhs) = delete; 

「= delete」確保複製構造函數不會自動提供。添加上面的行後,我得到一個錯誤報告說2 Use of deleted function test::test(const test&)。我的問題是:按照「內部C++對象模型」我不需要上述類的複製構造函數,所以當我明確說不生成複製構造函數(使用刪除)爲什麼我得到一個錯誤?因爲我期待編譯器不需要上述類的複製構造函數。

我使用的是gcc版本4.6.3。

+1

如果沒有提供_copy-constructor_,那麼您的語句2將不會編譯。 –

+0

它工作正常,如果我不添加測試(常量測試和rhs)在課堂上。 – user1431221

+0

語句2不使用默認構造函數,它使用複製構造函數,並且如果聲明瞭它並將其刪除(您所做的),那麼它將不會編譯,因爲語句2會匹配已刪除的簽名。 – birryree

回答

0

這條線:

test obj2(obj1) 

試圖調用拷貝構造函數。

8

對於類是可複製的,它需要有一個複製構造函數。無論你自己編寫,還是編譯器爲你生成一個,都沒關係 - 它必須可用於test a; test b(a);纔是有效的操作。

您明確強制編譯器刪除複製構造函數 - 這是舊版本的「make copy constructor private」技巧的新版本。它禁止複製。所以不要驚訝,你不能複製。因爲你告訴編譯器不允許它。

2

標準字上隱式生成複製構造是[class.copy]/7

如果類定義不明確地聲明一個拷貝構造,一種是隱式地聲明。如果類定義聲明瞭移動構造函數或移動賦值操作符,則隱式聲明的拷貝構造函數被定義爲刪除;否則,它被定義爲默認(8.4)。如果類具有用戶聲明的複製賦值運算符或用戶聲明的析構函數,則不推薦使用後一種情況。

[class.copy]/13

被默認和未限定的複製/移動構造爲已刪除的隱式定義的,如果它是ODR使用(3.2),或當它在首次聲明後明確默認。 [注意:即使實現忽略了odr用法(3.2,12.2),也會隱式地定義複製/移動構造函數。 -end note]如果隱式定義的構造函數滿足constexpr構造函數的要求(7.1.5),則隱式定義的構造函數isconstexpr。

所以一個拷貝構造test仍會生成,其過得去聲明2.調用我會相信「內部C++對象模型」在談論當拷貝構造不不重要的。

+0

描述了拷貝ctor是否被聲明爲_declared_,關於何時隱式地_defined_(即生成) –

相關問題