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() 需要覆盖。

不,错误是因为D没有覆盖它们,所以函数调用有两个候选者。虚函数在两个直接基类中都会被覆盖,但不会在派生类中被覆盖,因此没有唯一的最终覆盖器。

您需要决定D::f()应该做什么,并相应地实施它。

于 2013-09-17T17:22:34.770 回答
0

错误不在您指示的行中,而是在D. 该定义完全不正确,因为虚函数没有唯一的最终覆盖器。

于 2013-09-17T17:13:09.907 回答
0

您有 2 个来自 B 类和 C 类的具有相同签名的函数,因此成员函数f()是不明确的(您已经指出)。

于 2013-09-17T17:20:29.277 回答
-1

也许 ap = bp 有隐式转换,这样 ap->f() 将被识别为 B::f,但 dp 有两个 f() 可供选择。

编辑:谁能解释为什么 ap->f() 不会抛出错误,但 dp->f() 会?

于 2013-09-17T17:18:38.273 回答