8

私はこれを経験していました:- https://isocpp.org/wiki/faq/multiple-inheritance#mi-delegate-to-sister

誰かがこれがどのように発生し、なぜこれが発生するのかを説明してもらえますか?

4

3 に答える 3

10

他の 2 つの回答に欠けている重要な点は、仮想継承が存在することです。これは、完全なオブジェクトには、 と によって共有されるサブオブジェクトが 1 つしかないことを意味しますBaseDer1Der2

Der1および型のそれぞれDer2は、そのベースの仮想関数の 1 つの実装を提供します。そのようなオブジェクトは 1 つしかないため、 と の組み合わせによりDer1、完全なオブジェクト内で両方のメンバーDer2の実装が提供されます。

実際に型のメンバー関数を呼び出しているため、兄弟クラスにディスパッチでき、その関数は(兄弟クラスによって) サブオブジェクトBaseに実装されます。は を呼び出すのではなく、たまたま にある最終的なオーバーライドにディスパッチされることにBase注意してください。これは、他の場合の最終オーバーライダーへのディスパッチと実際には違いはありません。Der1Der2::barBase::barDer2

struct base { virtual void f() = 0; };
struct d : base { void g() { f(); } };
struct d1 : d { void f() { std::cout << "here"; };
int main() {
   d1 x;
   x.g(); // dispatches from 'd::g' to 'd1::f' which is below in the hierarchy!
          // yeah, right, everyone knows that... no magic here
}

継承が仮想でない場合Base、完全な型には 2 つのサブオブジェクトがあり、それぞれが (異なる) 純粋仮想関数を持ち、最も派生した型のオブジェクトをインスタンス化することさえできません (それがない限り)。仮想機能の定義を提供)

于 2013-06-24T17:32:33.833 に答える
1

簡単
に言えば、Join クラスは Der1 と Der2 から派生していますが、Base クラスのインスタンスは 1 つしかありません。これは、仮想継承によるものです。基本クラスが抽象クラスではなく、いくつかの引数をコンストラクターに渡す必要がある場合、これらの呼び出しは Der1 と Der2 の両方で省略され、これらの引数を結合を介して渡す必要があります。

于 2013-06-24T16:36:10.763 に答える