「仮想基本クラス」とは何か、そしてそれが何を意味するのかを知りたいです。
例を挙げてみましょう:
class Foo
{
public:
void DoSomething() { /* ... */ }
};
class Bar : public virtual Foo
{
public:
void DoSpecific() { /* ... */ }
};
ベストアンサー1
仮想継承で使用される仮想基本クラスは、多重継承を使用するときに、特定のクラスの複数の「インスタンス」が継承階層に出現するのを防ぐ方法です。
次のシナリオを考えてみましょう。
class A { public: void Foo() {} };
class B : public A {};
class C : public A {};
class D : public B, public C {};
上記のクラス階層の結果、「恐ろしいダイヤモンド」は次のようになります。
A
/ \
B C
\ /
D
D のインスタンスは、A を含む B と、A を含む C で構成されます。つまり、A の「インスタンス」が 2 つあることになります (適切な表現が見つからないため)。
このようなシナリオでは、曖昧さが生じる可能性があります。これを実行すると何が起きますか。
D d;
d.Foo(); // is this B's Foo() or C's Foo() ??
この問題を解決するために仮想継承があります。クラスを継承するときに仮想を指定すると、コンパイラーに単一のインスタンスのみが必要であることを伝えることになります。
class A { public: void Foo() {} };
class B : public virtual A {};
class C : public virtual A {};
class D : public B, public C {};
これは、階層に含まれるAの「インスタンス」が1つだけであることを意味します。したがって、
D d;
d.Foo(); // no longer ambiguous