C++ 中的不对称虚拟继承钻石

发布于 2024-07-30 00:15:12 字数 1366 浏览 7 评论 0原文

所以我有这个想法,我认为在C++中基本上不可能实现......但我想问一下。 我通读了 Stroustrup 的第 15 章,但没有得到答案,而且我认为有关继承钻石的其他数十亿个问题也无法回答这个问题,所以我在这里提问。

问题是,当您从两个基类继承时会发生什么,这两个基类本身共享一个公共基类,但实际上这两个基类中只有一个继承自该基类。 例如:

class CommonBase { ... };

class BaseA : CommonBase { ... };

class BaseB : virtual CommonBase { ... };

class Derived : BaseA, BaseB { ... };

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

    LibBase
         | \
         |  \ 
         |   MyBase
         |     |
         |     |
 LibDerived    |
         | \   |
         |  \  |
         |   MyDerived
         |     |
LibDerived2    |
         | \   |
         |  \  |
         |   MyDerived2
         |     |
LibDerived3    |
         | \   |
         |  \  |
         |   MyDerived3
         |     |
LibConcrete    |
           \   |
            MyConcrete

明白图片了吗? 我希望每个“My”类的对象成为它们实质上要替换的类的对象,但我希望继承图中的下一个类使用来自“My”基类的重写方法实现,但来自库类的所有其他方法。 库类不会虚拟继承,所以它是这样的

class LibDerived : LibBase

但是如果我让我的类虚拟继承

class MyBase : virtual LibBase {};
class MyDerived: virtual MyBase, virtual LibDerived {};

因为MyDerived将有一个vtable,并且MyBase将有一个vtable,会不会有只有一个 LibBase 对象?

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

So I have this idea and I think it's basically impossible to implement in C++... but I want to ask. I read through chapter 15 of Stroustrup and didn't get my answer, and I don't think the billion other questions about inheritance diamonds answer this one, so I'm asking here.

The question is, what happens when you inherit from two base classes which share a common base class themselves, but only one of the two inherits from it virtually. For example:

class CommonBase { ... };

class BaseA : CommonBase { ... };

class BaseB : virtual CommonBase { ... };

class Derived : BaseA, BaseB { ... };

The reason I think I want to do this is because I'm trying to extend an existing library without having to recompile the whole library (don't want to open that can of worms). There already exists a chain of inheritance that I would like to modify. Basically something like this (excuse the ascii art)

    LibBase
         | \
         |  \ 
         |   MyBase
         |     |
         |     |
 LibDerived    |
         | \   |
         |  \  |
         |   MyDerived
         |     |
LibDerived2    |
         | \   |
         |  \  |
         |   MyDerived2
         |     |
LibDerived3    |
         | \   |
         |  \  |
         |   MyDerived3
         |     |
LibConcrete    |
           \   |
            MyConcrete

Get the picture? I want an object of each of "My" classes to be an object of the class they are essentially replacing, but I want the next class in the inheritence diagram to use the overridden method implementation from "My" base class, but all the other methods from the library's classes. The library classes do not inherit virtually so it's like this

class LibDerived : LibBase

But if I make my class inherit virtually

class MyBase : virtual LibBase {};
class MyDerived: virtual MyBase, virtual LibDerived {};

Since MyDerived will have a vtable, and MyBase will have a vtable, will there be only one LibBase object?

I hope this question is clear enough.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

送你一个梦 2024-08-06 00:15:13

本质上,你是对的。 如果您希望这种继承树发挥作用,您需要从 LibBase 虚拟派生出 LibDerived

如果您没有这个,则无法阻止在 LibDerived 下拥有一个非虚拟 LibBase 以及在 LibBase 下拥有一个单独的虚拟 LibBase >MyBase。

Essentially, you are right. You need to have LibDerived derived virtually from LibBase if you want this sort of inheritance tree to work.

If you don't have this you can't prevent having a non-virtual LibBase under the LibDerived and a separate virtual LibBase under MyBase.

も让我眼熟你 2024-08-06 00:15:12

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

class LibDerived : LibBase

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

class MyBase : virtual LibBase {};

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

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

To simplify answer let's think about virtual/non-virtual as duplicated or non-duplicated content.

class LibDerived : LibBase

declares: I allow LibBase be twice (or more ) entered into descending of LibDerived

class MyBase : virtual LibBase {};

declares: I allow compiler to optimize two entries of LibBase in MyBase descendings into single one.

When these two declarations meet each one, the first is more priority so MyDerived gets 2 implmentation of LibBase. But power of c++ is possibility to resolve it! Just make overriding on MyDerived virtual functions to select which you want to use. Ore another way - create universal wrapper of MyDerived derived from interface LibBase that aggregate any instance: LibDerived, MyBase, ... and call expected method from aggregate.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文