2012-05-10 13 views
1

BがAから派生した場合、たとえばBの新しいオブジェクトを作成すると、Aのコンストラクタが最初に呼び出されることがわかっています。オブジェクトbを破壊すると、Bのデストラクタが最初にコールします。次に、ベースクラスに複数のコンストラクタがある場合、どのコンストラクタが呼び出されるのでしょうか?ここで質問があります。なぜ?派生クラスと基本クラスの間のコンストラクタの呼び出し順序

私は下に1つのテストプログラムを書いていますが、これはBaseクラスのデフォルトのコンストラクタを呼び出すと思いますが、それは単なる偶然であるかどうか分かりません。

#include <iostream> 
using namespace std; 

class A{ 
    public: 
    A(int i){cout<<"A con with param"<<endl;} 
    A(){cout<<"A con"<<endl;} 
    ~A(){} 
}; 

class B : public A 
{ 
    public: 
    B(int i){cout<<"B con with param"<<endl;} 
    B(){cout<<"B con"<<endl;} 
    ~B(){} 
}; 

int main() 
{ 
    B b(5); 
    return 0; 
} 

この問題を解明する理由やアドバイスを教えてくれるボスがいるのでしょうか?

+0

あなたの例では、 'A'の空のコンストラクタ(引数なし)を呼び出すように指定していないので、' A'() 'は常に' B'コンストラクタから呼び出されます。同様の質問:http://stackoverflow.com/questions/8093882/using-c-base-class-constructorsまたはhttp://stackoverflow.com/questions/10001524/how-to-force-base-class-constructors-to派生クラスと呼ばれる – birryree

答えて

3

あなたが書く場合:

B(int i) { cout<<"B con with param"<<endl; } 

を、その後(引数なし)コンストラクタA()が呼び出されます。

あなたが書く場合:その後、

B(int i): A(i) { cout<<"B con with param"<<endl; } 

A(int)が呼び出されますコンストラクタです。

+0

ああ、私はそれを持っています!基本クラスのコンストラクタの選択は、派生クラスのコンストラクタの初期化子リストで決定されます。指定しない場合、Baseクラスのデフォルトのコンストラクタが呼び出されます。 –

+0

そうです、そうです。 –

1

プログラミングでは偶然ではありません。
int引数を明示的に基底クラスに渡さなかったため、デフォルトコンストラクタが呼び出されました。

基本クラスの他のコンストラクターを呼び出すには、派生クラスのコンストラクターが、基本クラスコンストラクターにパラメーターを渡す必要があります。
はいわゆるべきA(int)のために、あなたは初期化子リストで明示的に他のいくつかのコンストラクタを呼び出さない限り、親クラスの空のコンストラクタが呼び出されますB():A(some_int)またはB(int):A(some_int)

0

を持っている必要があります。

EDIT:

B(int i) : A(i) { 
    ... do stuff ... 
} 
0

初期化の順序は、もう少し複雑に比べて次のとおりです。ここでは、明示的にコンストラクタを呼び出す方法です。技術的には、ほとんどオブジェクトのの初期化リストから開始されます。そのコンストラクタは、オブジェクトが作成されている場所から通常のオーバーロードの解像度で選択されます。 の初期化リストで最も派生した型コンストラクタは、ベースのコンストラクタを(明示的にまたは暗黙的に)リストします。また、ベースのコンストラクタも初期化リストの呼び出しでオーバーロード解決を使用して選択されます。ベースが初期化リストに明示的に記述されていない場合、コンパイラはデフォルトコンストラクタへの呼び出しを注入します。

正確な構成の順序は、初期化される最初のサブオブジェクトが特定の順序(深さ - 最初、左から右への左から右への基底クラス宣言の宣言の順序)。すべての仮想基底が初期化されると、最も派生した型の直接非仮想基底が宣言の順序(左から右)で再び初期化されます。すべての基底が初期化されると、クラスの宣言の順番でメンバーが初期化されます。

すべてのケースで、コードはサブオブジェクトを初期化リストに明示的にリストすることができ、そこにリストされているコンストラクタが使用されるか、またはエンティティがリストされていない場合はデフォルトコンストラクタが使用されます。