23
class A {
        int i;
public: 
        A() {cout<<"in A's def const\n";};
        A(int k) {cout<<"In A const\n";  i = k; }
        };

class B : virtual public A {
public:
        B(){cout<<"in B's def const\n";};
        B(int i) : A(i) {cout<<"in B const\n";}
        };

class C :   public B {
public:
        C() {cout<<"in C def cstr\n";}
        C(int i) : B(i) {cout<<"in C const\n";}
        };

int main()
{
        C c(2);
        return 0;
}

この場合の出力は

in A's def const
in B const
in C const

なぜこれが参入しないのかin A const

`1 arg コンストラクター呼び出しの順序に従う必要があります。しかし、仮想キーワードを使用して A から B を派生させると実際に何が起こっているのでしょうか。

もう少し質問があります

上記のプログラムで virtual キーワードを削除し、デフォルトのコンストラクターをすべて削除しても、エラーが発生します。では、なぜ def コンストラクターが必要なのか

4

3 に答える 3

18

仮想基本クラスのコンストラクターは、渡される可能性のある引数を使用して、常に最も派生したクラスから呼び出されます。あなたの場合、最も派生したクラスは の初期化子を指定していないAため、デフォルトのコンストラクターが使用されます。

于 2012-05-10T12:44:39.123 に答える
8

JamesKanzeが説明したように、継承の場合virtual、仮想基本クラスのコンストラクターを呼び出すのは最も派生したクラスです。したがって、A整数を受け取るコンストラクターが必要な場合は、それをC初期化リストに追加する必要があります。

C(int i) : A(i), B(i) {cout<<"in C const\n";}

質問の2番目の部分では、デフォルトコンストラクターは必要ありませんが、デフォルト以外のコンストラクターがないとコンパイラーはそれを実行できないため、派生クラスはデフォルト以外のコンストラクターを明示的に呼び出す必要があります。

#include <iostream>
using namespace std;

class A {
  int i;
public:
  // A() {cout<<"in A's def const\n";};
  A(int k) {cout<<"In A const\n";  i = k; }
};

class B : virtual public A {
public:
  // B(){cout<<"in B's def const\n";};
  B(int i) : A(i) {cout<<"in B const\n";}
};

class C :   public B {
public:
  C() : A(42), B(42) {cout<<"in C def cstr\n";}
  C(int i) : A(i), B(i) {cout<<"in C const\n";}
};

int main()
{
  C c(2), c2;
  return 0;
}

これは印刷されます

In A const
in B const
in C const
In A const
in B const
in C def cstr
于 2012-05-10T13:11:57.243 に答える
2

ここで 2 つの質問があります。

これがA constに入らないのはなぜですか?

仮想継承を使用しているためです。

仮想継承を使用する場合、最も派生したクラスの ctor の初期化リストは、仮想基本クラスの ctor を直接呼び出します。. この場合、それはのコンストラクターがのコンストラクターを直接C呼び出すことを意味します。の初期化リストで呼び出すコンストラクタを指定していないため、デフォルトのコンストラクタが呼び出されます。AAC

これは、の実装を次のように変更することで修正されますC::C(int)

C(int i) : A(i), B(i) {cout<<"in C const\n";}

上記のプログラムで virtual キーワードを削除し、デフォルトのコンストラクターをすべて削除すると、エラーが発生します。では、なぜ def コンストラクターが必要なのでしょうか?

呼び出すctorBも指定しないAため、デフォルトのコンストラクターが使用されます。As def ctorを削除すると、Bコンパイルできなくなります。

于 2012-05-10T13:15:39.340 に答える