2008-12-07 87 views
148

爲什麼驗證碼:繼承構造

class A 
{ 
    public: 
     explicit A(int x) {} 
}; 

class B: public A 
{ 
}; 

int main(void) 
{ 
    B *b = new B(5); 
    delete b; 
} 

導致這些錯誤:

 
main.cpp: In function ‘int main()’: 
main.cpp:13: error: no matching function for call to ‘B::B(int)’ 
main.cpp:8: note: candidates are: B::B() 
main.cpp:8: note:     B::B(const B&) 

應該不是B繼承的構造?

(這是使用gcc)

回答

248

在C++ 03標準構造函數不能被繼承,你需要通過自己調用基類實現手動逐個地繼承它們。如果您的編譯器支持C++ 11標準,則會有構造函數繼承。欲瞭解更多信息,請參閱Wikipedia C++11 article。隨着新標準的編寫:

class A 
{ 
    public: 
     explicit A(int x) {} 
}; 

class B: public A 
{ 
    using A::A; 
}; 
+9

這是因爲一年多了,一直沒有任何編譯器能夠真正建立在上面的代碼:-) – Mikhail 2013-01-21 04:51:43

+11

@Mikhail相當邪惡:兩個鐺和g ++現在應該支持繼承構造函數: HTTP://鐺.llvm.org/cxx_status.html http://gcc.gnu.org/projects/cxx0x.html 建議使用upvoting這一個作爲正確的答案。 – 2013-05-05 11:46:39

+0

只是問,繼承的構造函數是否能夠訪問/初始化基類的私有成員?或者我是否必須將它們指定爲受保護的? – Markasoftware 2014-06-22 05:13:40

4

你必須明確地定義B中的構造函數和顯式調用父構造函數。

B(int x) : A(x) { } 

B() : A(5) { } 
80

構造不被繼承。它們被子構造函數隱式地或顯式地調用。

編譯器創建一個默認構造函數(一個沒有參數)和一個默認的複製構造函數(一個參數是對同一類型的引用)。但是如果你想要一個接受int的構造函數,你必須明確地定義它。

class A 
{ 
public: 
    explicit A(int x) {} 
}; 

class B: public A 
{ 
public: 
    explicit B(int x) : A(x) { } 
}; 

UPDATE:在C++ 11,構造函數可以繼承。有關詳情,請參閱Suma的回答。

1

正確的代碼

class A 
{ 
    public: 
     explicit A(int x) {} 
}; 

class B: public A 
{ 
     public: 

    B(int a):A(a){ 
      } 
}; 

main() 
{ 
    B *b = new B(5); 
    delete b; 
} 

錯誤是B B/C級還沒有參數的構造函數和第二它應該有基類初始調用基類的構造函數參數的構造函數

3

這是直接從Bjarne Stroustrup's page

如果你選擇,你仍然可以拍攝自己的腳被我在派生類中定義構造函數,在其中定義需要初始化的新成員變量:

struct B1 { 
    B1(int) { } 
}; 

struct D1 : B1 { 
    using B1::B1; // implicitly declares D1(int) 
    int x; 
}; 

void test() 
{ 
    D1 d(6); // Oops: d.x is not initialized 
    D1 e;  // error: D1 has no default constructor 
} 
1

如何使用模板函數來綁定所有構造函數?

template <class... T> Derived(T... t) : Base(t...) {}