15

仮想基本クラスがどのように機能するかについて少し混乱しています。特に、基本クラスのコンストラクターがどのように呼び出されるのか疑問に思っていました。私はそれを理解するために例を書きました:

#include <cstdio>
#include <string>
using std::string;

struct A{
    string s;
    A() {}
    A(string t): s(t) {}
};

struct B: virtual public A{
    B(): A("B"){}
};

struct C: virtual public A {};

struct D: public B, public C {};

struct E: public C, public B {};

struct F: public B {};

int main(){
    D d;
    printf("\"%s\"\n",d.s.c_str());
    E e;
    printf("\"%s\"\n",e.s.c_str());
    F f;
    printf("\"%s\"\n",f.s.c_str());
    B b;
    printf("\"%s\"\n",b.s.c_str());
}

どの出力

""
""
""
"B"

最初の 2 つのケースでは何が起こるかわかりませんでしたが、少なくとも 3 番目のケースでは、出力が「B」になると予想していました。だから今、私はただ混乱しています。A のコンストラクターがどのように呼び出されるかを理解するためのルールは何ですか?

4

2 に答える 2

10

コンストラクター呼び出しは常に1つだけであり、インスタンス化する実際の具象クラスは常に存在します。のコンストラクターで行ったように、必要に応じて基本クラスのコンストラクターを呼び出すコンストラクターを各派生クラスに付与するのはユーザーのB責任です。

更新:要点を見逃してすみません!イルジャーンに感謝します。

ただし、は実質的にからB継承します。標準(FIDSでは10.1.4)によると、「仮想的に指定された個別の基本クラスごとに、最も派生したオブジェクトには、そのタイプの単一の基本クラスサブオブジェクトが含まれる必要があります」。あなたの場合、これは、ベースを構築するときに、クラスが'sではなく'デフォルトのコンストラクターをすぐに呼び出すことを意味します。AFAB

于 2011-06-23T23:28:33.503 に答える
7

仮想基本クラスは、常に最も派生したクラスによって構築されます。

于 2011-06-23T23:34:40.733 に答える