Inheritance Asymmetric Virtual Diamond in C ++

So, I have this idea, and I think it is almost impossible to implement in C ++ ... but I want to ask. I read chapter 15 of the Stroustrup and didn’t get an answer, and I don’t think that we will answer a billion other questions about inheritance diamonds, so I ask here.

The question is what happens when you inherit from two base classes that share a common base class, but only one of the two inherits from it in practice. For instance:

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

I think I want to do this because I am trying to expand an existing library without recompiling the entire library (I do not want to open this worm from worms). There is already an inheritance chain that I would like to change. Basically something like this (sorry ascii art)

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

Get an image? I want the object of each class " My " to be an object of the class, which they essentially replace, but I want the next class in the inheritance diagram to use the implementation of the overridden method from the base class " My ", but also all other methods from the library classes. Library classes do not inherit almost as it looks

 class LibDerived : LibBase 

But if I make my class inheritable practically

 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?

Hope this question is clear enough.

+4
source share
2 answers

To simplify the answer, think of virtual / non-virtual as duplicated or non-duplicated content.

 class LibDerived : LibBase 

announces: I allow LibBase to double (or more) enter LibDerived

 class MyBase : virtual LibBase {}; 

announces: I allow the compiler to optimize two LibBase entries in MyBase streams into one.

When these two declarations correspond to each of them, the first is more priority, therefore MyDerived receives 2 LibBase injections. But the power of C ++ is the ability to solve it! Just override the MyDerived virtual functions to choose what you want to use. Another way is to create a universal MyDerived shell, obtained from the LibBase interface, which combines any instance: LibDerived, MyBase, ... and calls the expected method from the collection.

+2
source

In fact, you are right. You must have LibDerived obtained actually from LibBase if you want this inheritance tree tree to work.

If you do not have this, you cannot prevent the presence of a non-virtual LibBase under LibDerived and a separate virtual LibBase under MyBase .

+2
source

All Articles