簡體   English   中英

什么時候在C ++中生成默認構造函數

[英]When is default constructor generated in C++

根據“ Inside 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;

“ =刪除”確保不會自動提供副本構造函數。 添加以上行后,我得到了語句2的錯誤,該語句表明Use of deleted function test::test(const test&)

我的問題是:根據“內部C ++對象模型”,我不需要上述類的復制構造函數,因此當我明確地說不生成復制構造函數(使用Delete)時,為什么會出現錯誤? 由於我期望編譯器不需要上述類的復制構造函數。

我正在使用gcc版本4.6.3。

為了使類可復制,它需要一個復制構造函數。 無論您是編寫自己的代碼,還是編譯器為您生成代碼,都沒關系-它必須可用於test a; test b(a); test a; test b(a); 是有效的操作。

您顯式強制編譯器刪除復制構造函數—這是舊的“使復制構造函數為私有”技巧的新版本。 它不允許復制。 因此,您不能復制就不會感到驚訝。 因為您告訴編譯器不允許這樣做。

隱式生成的副本構造函數的標准詞是[class.copy] / 7

如果類定義未明確聲明一個副本構造函數,則將隱式聲明一個副本構造函數。 如果類定義聲明了move構造函數或move賦值運算符,則隱式聲明的copy構造函數將定義為delete; 否則,將其定義為默認值(8.4)。 如果該類具有用戶聲明的副本分配運算符或用戶聲明的析構函數,則不建議使用后者。

[class.copy] / 13

如果默認使用且未定義為刪除的copy / move構造函數,則它是odr-used(3.2)或在其第一次聲明后顯式默認的隱式定義。 [注意:即使實現省略了odr-use(3.2、12.2),也隱式定義了copy / move構造函數。 — —注釋[end note]如果隱式定義的構造函數將滿足constexpr構造函數(7.1.5)的要求,則隱式定義的構造函數為constexpr。

因此,仍會生成一個用於test復制構造函數 ,並由語句2調用它。我相信“ Inside C ++ Object Model”在談論復制構造函數的重要性。

這行:

test obj2(obj1)

正在嘗試調用復制構造函數。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM