2011-04-25 31 views
14
class A : public B 
{ 
    ... 
} 

// case I : explicitly call the base class default constructor 
A::A() : B() 
{ 
... 
} 

// case II : don't call the base class default constructor 
A::A() // : B() 
{ 
... 
} 

情況II是否等於情況I?C++ - 我應該在初始化列表中調用基類默認構造函數嗎?

對我來說,我假設base clasa B的默認構造函數在情況II中不被調用。

感謝您從VS2008

B constructor 
A constructor 
Press any key to continue . . . 

回答

21

基類構造函數被調用在這兩種情況下

///更新///

class B 
{ 
public: 
    B() 
    { 
     cout << "B constructor" << endl; 
    } 
}; 
class A : public B 
{ 
public: 
    A() 
    { 
     cout << "A constructor" << endl; 
    } 
}; 

int _tmain(int argc, _TCHAR* argv[]) 
{ 
    A a; 
    return 0; 
} 

//輸出。

這是一個link文章與更多的信息。

+0

鏈接非常好:) - 謝謝 – q0987 2011-04-25 16:07:22

7

如果基類構造函數沒有使用任何參數,則不需要在初始化列表中明確提及它。

1

每個派生自其他類的類都必須調用基類的構造函數。派生類只能在所有基類完全構建後才能構造。因此,如果您調用基類的構造函數或不。如果你沒有調用,只要有一個默認的構造函數供編譯器確定,它就會被調用。否則編譯器會拋出錯誤。

4

爲了完成學習體驗並加深理解,您可以稍微修改一下。例如,B沒有默認構造函數時會發生什麼?它甚至編譯?像這樣的其他輕微修改將提供很好的學習體驗。

這就是說,在我的經驗是一般更好地做到這

A::A() : B() { ... } 

A::A() { ... } 

,因爲前者更明確的,它將讓你去思考什麼是真正回事與基類初始化。通過明確地說明事情,你可能會避免隱藏的行爲。

+0

我給了你一個加號,因爲你提出了一些方法來提高對這個主題的理解。 – Krythic 2014-12-02 23:04:14

+0

我給了+1,因爲這回答了「應該......」的問題。大多數其他答案是針對相關問題「必須......」。 – 2017-03-06 17:19:46

3

如果B沒有用戶聲明的構造函數,則行爲是不同的。比較:現在

struct SimpleAggregate { 
    int a; 
    float b; 
}; 

struct ClassWrapper : SimpleAggregate { 
    ClassWrapper() : SimpleAggregate() { } 
}; 

ClassWrapper w; 

w.aw.b保證是零。如果你沒有明確初始化基類,它們將會有不確定的值。


這可能是您不知道的是,儘管語法,上述使用的SimpleAggregate()調用默認的構造函數,雖然。它只是初始化基類的值(我們在Stackoverflow上有幾個關於「初始值」的好答案),而不是調用默認的構造函數,因爲沒有用戶聲明。

相關問題