2015-02-11 85 views
10

我有下面的代碼:複製構造是不能繼承

class C { 
public: 
    C(int) {} 
    C(const C&) {} 
    C() {} 
}; 

class D : public C { 
public: 
    using C::C; 
}; 

int main() { 
    C c; 
    D d_from_c(c); // does not compile, copy ctor is not inherited 
    D d_from_int(1); // compiles, C(int) is inherited 
} 

派生類要繼承基礎的所有構建函數,除了默認的構造函數(它被解釋here)。但爲什麼copy ctor還沒有被繼承?來自相關問題的爭論在這裏是不能接受的。

該代碼是用g ++ 4.8.1編譯的。

回答

12

因爲標準是這樣說的。 [class.inhctor]/P3,重點煤礦:

對於在候選集合中繼承 構造比沒有參數或具有單個參數 複製/移動的構造構造其他的每個非模板構造,構造函數是 隱含聲明具有相同的構造函數特性除非 有一個用戶聲明的構造函數具有 完整類中的相同簽名,其中使用聲明出現或構造函數 將是默認,複製或移動該類的構造函數。

10

派生類要繼承基礎的所有構建函數,除了默認的構造函數

不,這不是真的,看到T.C.'s answer爲真正的規則。

繼承構造函數的目的是說「派生類型可以使用與基類型相同的參數來創建」,但這與基類的複製構造函數無關,因爲複製構造函數不僅僅是一種說法,如何從給定的參數創建一個類型。

複製構造函數是特殊的,它用於複製相同類型的對象。

構造函數D(const C&)不會用於複製相同類型的對象,因爲CD不是同一類型。

0

有一段時間,我們假定允許「複製構造函數繼承」。 讓您的課堂結構保持不變,請考慮下面的代碼修改主要方法。

int main() { 
    C c; 
    D d; 
    D d_from_d(d); 
    D d_from_c(c); // does not compile, copy ctor is not inherited 
    D d_from_int(1); // compiles, C(int) is inherited 
} 

D d_from_d(d),作爲一個正常的構造函數調用,將有兩個拷貝構造函數調用。一個用於C :: C(const C &),另一個用於D的編譯器生成拷貝構造函數。在D中有源對象類型(在這種情況下爲d)時,C的拷貝構造函數可以在編譯器生成D拷貝時複製C的屬性構造函數可以複製D的屬性。

但在D d_from_c(c)的情況下,C的拷貝構造函數沒有問題,因爲c的C屬性可以被C的拷貝構造函數拷貝。但是編譯器如何生成D的拷貝構造函數知道如何從C的對象中複製'D的屬性'。這是一個應該避免的衝突。但是,如果你提供某種'奇怪的拷貝構造函數'(你也可能需要一個默認的構造函數),比如:

D(const C & c):C(c){} 

然後, 調用D d_from_c(c); 是有效的。因爲,現在我們明確提供了一個匹配的「複製」構造函數。

因此,說'現在允許繼承複製構造函數'是無效的。