C++中的非对称虚拟继承菱形

che*_*kow 5 c++ multiple-inheritance virtual-inheritance

所以我有这个想法,我认为用C++实现基本上是不可能的...但我想问一下.我读完Stroustrup的第15章并没有得到我的答案,我认为关于继承钻石的其他十亿个问题没有回答这个问题,所以我在这里问.

问题是,当你从两个共享一个公共基类的基类继承时会发生什么,但是这两个基类中只有一个虚拟地从它继承.例如:

class CommonBase { ... };

class BaseA : CommonBase { ... };

class BaseB : virtual CommonBase { ... };

class Derived : BaseA, BaseB { ... };
Run Code Online (Sandbox Code Playgroud)

我认为我想这样做的原因是因为我试图扩展现有的库而不必重新编译整个库(不想打开那些蠕虫).已经存在我想要修改的继承链.基本上是这样的(原谅ascii艺术)

    LibBase
         | \
         |  \ 
         |   MyBase
         |     |
         |     |
 LibDerived    |
         | \   |
         |  \  |
         |   MyDerived
         |     |
LibDerived2    |
         | \   |
         |  \  |
         |   MyDerived2
         |     |
LibDerived3    |
         | \   |
         |  \  |
         |   MyDerived3
         |     |
LibConcrete    |
           \   |
            MyConcrete
Run Code Online (Sandbox Code Playgroud)

得到图片?我希望每个的"的对象My"类它们基本上更换类的对象,但我想在使用来自重写的方法执行的传承图中的下一个类" My"基类,但是所有的其它方法从图书馆的课程.库类几乎没有继承,所以就像这样

class LibDerived : LibBase
Run Code Online (Sandbox Code Playgroud)

但如果我让我的班级继承虚拟

class MyBase : virtual LibBase {};
class MyDerived: virtual MyBase, virtual LibDerived {};
Run Code Online (Sandbox Code Playgroud)

既然MyDerived会有一个vtable,并且MyBase会有一个vtable,那么只有一个LibBase对象吗?

我希望这个问题足够清楚.

Dew*_*wfy 2

为了简化答案,让我们将虚拟/非虚拟视为重复或非重复的内容。

class LibDerived : LibBase
Run Code Online (Sandbox Code Playgroud)

声明:我允许 LibBase 两次(或更多)进入 LibDerived 的降序

class MyBase : virtual LibBase {};
Run Code Online (Sandbox Code Playgroud)

声明:我允许编译器将 MyBase 降序中的 LibBase 的两个条目优化为单个条目。

当这两个声明满足时,第一个声明具有更高的优先级,因此 MyDerived 获得 LibBase 的 2 个实现。但是c++的强大功能可以解决这个问题!只需重写 MyDerived 虚拟函数即可选择您要使用的函数。或者另一种方式 - 创建从接口 LibBase 派生的 MyDerived 的通用包装器,该包装器聚合任何实例:LibDerived、MyBase...并从聚合中调用预期方法。