2012-03-11 122 views
1

我得到的錯誤:沒有適當的默認構造函數B.但是,我不明白爲什麼編譯器想調用默認構造函數,當我給參數ii和DONT要調用默認。繼承:沒有適當的默認構造函數可用

#include <iostream> 
using namespace std; 

class A { 
    int i; 
public: 
    A(int ii) { i = ii; cout << "Constructor for A\n"; } 
    ~A() { cout << "Destructor for A\n"; } 
    void f() const{} 
}; 

class B { 
    int i; 
public: 
    B(int ii) { i = ii; cout << "Constructor for B\n"; } 
    ~B() { cout << "Destructor for B\n"; } 
    void f() const{} 
}; 

class C:public B { 
    A a; 
public: 
    C() { cout << "Constructor for C\n"; } 
    ~C() { cout << "Destructor for C\n"; } 
    void f() const { 
     a.f(); 
     B::f(); 
    } 
}; 

class D:public B { 
    C c; 
public: 
    D(int ii) { B(ii); cout << "Constructor for D\n"; } 
    ~D() { cout << "Destructor for D\n"; } 
}; 

int main() { 
    D d(47); 
} 

回答

4

你的父類的構造應該叫在初始化列表:

class D:public B { 
    C c; 
public: 
    D(int ii) : B(ii)/* <- */ { cout << "Constructor for D\n"; } 
    ~D() { cout << "Destructor for D\n"; } 
}; 

注意/ * < - * /註釋。這需要改變。

什麼你現在正在做的是在你d類的構造函數,它沒有被用來創建B()的一個實例:

D(int ii) { B(ii); /* <- useless*/ } 
+0

明白了..謝謝 – talha099 2012-03-11 18:10:24

+0

C也繼承B. – 2012-03-11 18:13:46

+0

這是同樣的解決方案,對不對? – mfontanini 2012-03-11 18:17:49

2
D(int ii) { B(ii); cout << "Constructor for D\n"; } 

通話B默認構造函數。 B(ii)創建一個B的臨時對象,只要D的構造函數返回,它就會被破壞。簡而言之,它不會調用正在構造的對象的基類的構造函數。

解決方案:
爲了能夠調用基類的構造特殊,你應該使用Member Initializer list

D(int ii) : B(ii) 
{ 
} 
+0

C也繼承自B. – 2012-03-11 18:13:55

+1

@LuchianGrigore:難怪它有同樣的問題。 OP不知道成員初始化列表,我認爲答案指出了它.OP的註釋表明S /他通過這裏的答案理解它,所以我不覺得有進一步的編輯需求的迫切需要。 – 2012-03-11 18:18:49

+0

夠公平的,只是指出來。 – 2012-03-11 18:20:36

1

此代碼:

class C:public B 
{ 
    C() { cout << "Constructor for C\n"; } 
}; 

嘗試請撥打B的默認構造函數。

你可能想:

class C:public B 
{ 
    C() : B(0) { cout << "Constructor for C\n"; } 
}; 

但是這取決於你的邏輯。

下面也是錯誤的:

D(int ii) { B(ii); cout << "Constructor for D\n"; } 

應該

D(int ii) : B(ii) { cout << "Constructor for D\n"; } 

在調用子類構造函數體基類構造函數只是創建一個臨時的對象,不會做任何東西。要獲得您期望的行爲,您必須調用初始值設定項列表中的構造函數。

1

您正在創建一個D,它是從B派生而來 - 但是D的ctor沒有將參數傳遞給B的構造函數,這會要求B有一個默認的ctor。

爲了解決這個問題,你通常需要編寫d提供的參數,B的構造函數:

class D : public B { 
    C C; 
public: 
    D(int ii) : B(ii) { cout << "ctor for D\n"; } 
}; 
1

你需要認識到,基地和成員子對象的輸入您的構造函數體的時間構造!也就是說,如果你有一個基地或成員不具有默認你需要通過它的參數在成員初始化列表:

D(int ii): B(ii) { std::cout << "constructor for D\n"; } 

在你的D構造的身體構造的對象只是一個臨時對象在你的情況下並不真正起到任何作用(臨時對象在某些情況下可能有用)。

相關問題