1

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

以下に 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;
}

この問題を解決するための理由やアドバイスを私に教えてくれる上司はいますか?

4

4 に答える 4

3

あなたが書く場合:

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

次に、コンストラクターA()(引数なし) が呼び出されます。

あなたが書く場合:

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

その後、コンストラクターA(int)が呼び出されます。

于 2012-05-10T13:01:30.930 に答える
1

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

基本クラスの他のコンストラクターを呼び出すには、派生クラスのコンストラクターがパラメーターを基本クラスのコンストラクターに渡す必要があります。
したがって、A(int)呼び出されるには、B():A(some_int)またはB(int):A(some_int)

于 2012-05-10T13:02:34.317 に答える
0

初期化リストで他のコンストラクターを明示的に呼び出さない限り、親クラスの空のコンストラクターが呼び出されます。

編集:コンストラクターを明示的に呼び出す方法は次のとおりです。

B(int i) : A(i) {
  ... do stuff ...
}
于 2012-05-10T13:03:03.847 に答える
0

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

初期化される最初のサブオブジェクトが特定の順序 (深さ優先、左から右、ここで左から右が宣言の順序) であるという点で、構築の正確な順序も少し複雑です。基底クラスの宣言)。すべての仮想ベースが初期化されると、最も派生した型の直接の非仮想ベースが、再び宣言の順序 (左から右) で初期化されます。すべてのベースが初期化されると、メンバーはクラスで宣言された順序で初期化されます。

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

于 2012-05-10T13:27:10.247 に答える