1

C++ における多重継承の問題:

ダイヤモンドの問題のように見えますが、そうではありません。仮想継承を追加しても解決できません。

struct A {
   virtual void f() { cout << "A::f()" << endl; };
};

struct B : public virtual A {
   void f() { cout << "B::f()" << endl;};
};

struct C :  public virtual A {
  void f() { cout << "C::f()" << endl;};
};

struct D : B, C { };

int main() {
  D d;

  B* bp = &d;
  A* ap = bp;
  D* dp = &d;

  ap->f();
  dp->f(); // compile error here because D has two candidates f() to override. 
        // error: request for member f is ambiguous
        // error: candidates are: virtual void C::f()
        // error:                 virtual void B::f()

  }

私は正しいですか?

4

4 に答える 4

4

ダイヤモンドの問題のように見えますが、そうではありません。

はい、そうです; それが古典的な「ダイヤモンド」パターンです。おそらく、問題はダイヤモンドの存在が原因ではないということですか? それは確かにそうだから、なぜその赤いニシンを質問に含めたのだろうか。より単純な例から同じ問題が発生します。

struct B {
   virtual void f() { cout << "B::f()" << endl;};
};

struct C {
   virtual void f() { cout << "C::f()" << endl;};
};

struct D : B, C { };

D にはオーバーライドする候補 f() が 2 つあるため、ここでコンパイル エラーが発生します。

いいえ、エラーはDオーバーライドされていないためです。そのため、関数呼び出しの候補は 2 つあります。仮想関数は両方の直接基底クラスでオーバーライドされますが、派生クラスではオーバーライドされないため、一意の最終オーバーライドはありません。

何をすべきかを決定D::f()し、それに応じて実装する必要があります。

于 2013-09-17T17:22:34.770 に答える