2010-10-03 148 views
3

我知道如果拷貝ctor在類中聲明爲private,編譯器將不會生成默認拷貝ctor。C++默認拷貝構造函數

但是有人能解釋爲什麼編譯器會這麼做嗎?

如果複製ctor被聲明爲受保護會發生什麼?編譯器會提供默認的copy ctor嗎?

如果複製ctor被聲明爲私有但有一個定義例如foo(const & obj){}

回答

4

在類中聲明的任何拷貝構造函數(無論是私有的,公共的還是受保護的)都意味着編譯器不會生成默認的拷貝ctor。無論是在類中聲明的那個定義還是定義,或者不僅控制具有適當可見級別代碼的代碼是否可以複製該類的實例(如果未定義,鏈接器會投訴;編譯器的工作僅僅是抱怨使用沒有適當的知名度,不要複製鏈接器的工作)。

例如,如果您聲明私人副本ctor,則只有在類中的函數(或朋友,當然)中的代碼被允許編譯,如果它試圖複製實例。如果沒有定義ctor,那麼該代碼將無法在鏈接器中生存下來,因此無論如何你都會得到一個錯誤(不幸的是,在構建過程中稍後會出現這種情況,也就是說,與之前相比,構建時可能會略微浪費計算資源 - 檢測到的錯誤)。

2

編譯器知道存在一個拷貝構造函數,所以它不會生成一個拷貝構造函數。無障礙(公共/私人/受保護)或其是否有定義在此階段不予考慮。

聽起來好像沒有複製構造函數就是因爲你不能從外部和非朋友調用私人函數。用戶定義的構造函數仍然存在,只是它是私人的。

如果它被保護,那麼只有子類和它本身可以調用複製構造函數。也不會有隱式定義的拷貝構造函數。

0

只要顯式聲明瞭複製構造函數,編譯器就不會生成默認的複製構造函數。無論明確聲明具有什麼隱私級別(私有,受保護或公開),情況都是如此。

1

$ 12月1日 - 「默認構造函數 (12.1),拷貝構造函數和拷貝 賦值運算符(12.8),和 析構函數(12.4)是特殊的成員 函數[注:執行 會。當 程序沒有明確 宣佈他們含蓄地宣佈對某些類類型這些成員 功能。實施將 隱含地定義他們,如果他們使用 。 [...]」

因此,如果拷貝構造函數是顯式聲明的,編譯器會將其作爲具有自定義拷貝構造函數的意圖,並且隱式拷貝構造函數的生成被抑制。

複製構造函數可以聲明並定義爲私有。如果複製構造函數被定義爲私有,則複製初始化/直接初始化將不起作用,如下所示。

struct A{ 
    A(){} 
private: 
    A(A const &){} 
}; 

int main(){ 
    A a1; 
    A a2(a1); // direct initialization, error 

    A a3 = a1; // copy initialization, error 
}