C での仮想継承
C で多重継承を扱う場合、仮想継承を理解することが重要です。次のコード スニペットを考えてみましょう。
class Base { public: Base(Base* pParent); /* implements basic stuff */ }; class A : virtual public Base { public: A(A* pParent) : Base(pParent) {} /* ... */ }; class B : virtual public Base { public: B(B* pParent) : Base(pParent) {} /* ... */ }; class C : public A, public B { public: C(C* pParent) : A(pParent), B(pParent) {} // - Compilation error here /* ... */ };
この例では、C は A と B の両方から継承し、さらにそれらは Base から仮想的に継承します。 GCC は、基本クラスに対してどのコンストラクターを呼び出すかを決定できないため、マークされた行でコンパイル エラーを発生させます。
説明:
仮想基本クラスには、独自の初期化メカニズムがあります。 。非仮想基本クラスとは異なり、仮想基本クラスは中間の基本クラスによって初期化されず、最も派生したクラスによって初期化されます。これは、ダイヤモンド継承階層では、各基本クラスが 1 回だけ定義され、最も派生したクラスによって 1 回だけ初期化される必要があるためです。
この例では、C が最も派生したクラスです。ただし、コンストラクターで Base クラスを明示的に初期化することはありません。したがって、GCC は Base のデフォルトのコンストラクターを使用しようとします。ただし、C は Base から直接継承していないため、デフォルトのコンストラクターにアクセスできず、コンパイル エラーが発生します。
解決策:
この問題を解決するには、 C のコンストラクターは、仮想基本初期化子を使用して Base クラスを明示的に初期化する必要があります:
class C : public A, public B { public: C(C* pParent) : A(pParent), B(pParent), Base(pParent) {} /* ... */ };
Base(pParent) 呼び出しを含めることによりC のコンストラクターでは、使用する Base コンストラクターを明示的に指定し、Base が適切に初期化されるようにします。
以上が仮想継承は C における複数の継承コンストラクターの初期化問題をどのように解決しますか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。