多个(菱形)继承编译时没有"虚拟",但没有

Ron*_*n_s 12 c++ virtual overriding multiple-inheritance virtual-inheritance

给定以下代码(没有虚拟继承):

class A
{
public:
    virtual void f() = 0;
};

class B : public A
{
 public:
    virtual void f() {}
};

class C : public A
{
 public:
    virtual void f() {}
};

class D : public B, public C
{

/* some code */
};


int main()
{
    D d;
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

代码编译.

另一方面,这里:

class A
{
public:
    virtual void f() = 0;
};

class B : virtual public A
{
    virtual void f() {}
};

class C : virtual public A
{
    virtual void f() {}
};

class D : public B, public C
{
    /* some code */
};


int main()
{
    D d;
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

编译器出现编译错误:

no unique final overrider for 'virtual void A::f()' in 'D' . 
Run Code Online (Sandbox Code Playgroud)

为什么第二个代码有所不同?

Alo*_*ave 9

您的第一个场景层次对应于:

    F()   F()
     A     A
     |     |
 F() B     C F()
      \   /
        D 
Run Code Online (Sandbox Code Playgroud)

D不是抽象的,因为在D型物体中有两个A子物体:一个是B通过B的格子混凝而另一个是通过C的格子混凝土制成的.

除非你尝试在D的对象上调用函数F(),否则不会有任何歧义.

您的第二个场景层次对应于:

       F()  
        A
      /   \
 F() B     C F()
      \   /
        D  
Run Code Online (Sandbox Code Playgroud)

在这种情况下,对象D具有单个基类A子对象,并且它必须覆盖并提供该子对象中纯虚函数的实现.


Herb Sutter在本周大师(GOTW)中的文章是多重继承的好读物:

  1. 多重继承第一部分
  2. 多重继承第二部分
  3. 多重继承第三部分

  • 即使A :: f()不是纯虚拟的,也会发生编译错误。参见[链接](http://ideone.com/H5padb) (2认同)

Che*_*Alf 7

使用虚拟继承,D对象具有单个基类A子对象.该单个子对象不能具有虚拟功能的两种不同实现.相比之下,没有虚拟继承,D对象有两个不同的基类A子对象,每个子对象都有自己的函数实现(在你试图在一个D对象上调用它之前一直没问题,此时你需要指出哪一个你想).

干杯和hth.