【问题标题】:multiple inheritance in C++, it looks like diamond but it is notC ++中的多重继承,它看起来像钻石,但它不是
【发布时间】:2013-09-17 17:05:17
【问题描述】:

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()

  }

我说的对吗?

【问题讨论】:

  • 钻石通常不是“问题”,而是解决方案...
  • 如果你画的时候看起来不像钻石,那是因为你画的不对……它是钻石!

标签: c++ inheritance multiple-inheritance diamond-problem


【解决方案1】:

看起来像钻石问题,其实不是。

是的,是的;这就是经典的“钻石”图案。也许您的意思是,问题不是由钻石的存在引起的?这当然是真的,所以我想知道你为什么在问题中加入了红鲱鱼。你会从一个更简单的例子中得到同样的问题:

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() 应该做什么,并相应地实施它。

【讨论】:

    【解决方案2】:

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

    【讨论】:

      【解决方案3】:

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

      【讨论】:

        【解决方案4】:

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

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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2019-10-09
          • 1970-01-01
          • 2016-09-21
          • 1970-01-01
          • 2013-05-16
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多