Multiple inheritance for solving abstract classes

Let's say I have 4 classes:

class I { public: virtual void X() = 0; }; class A : public virtual I { public: virtual void X() { } }; class B : public I { }; class C : public A, public B { }; 

I , B and C are abstract, where as A is not. If I just add virtual to the I inheritance for B , then A::X() resolves I::X() to C

However, I cannot change the source of B

My question is . Can I get A::X() to solve I::X for C without being able to change B ? I tried declaring A and B virtual for C no avail. I try not to have redundant code (for example, C declare X () {A :: X ();}). Any neat hacks?

In addition, there are a few questions very similar to this, but I could not find any talk about using virtual inheritance. Please point me if I missed this.

+6
source share
3 answers

This is pretty good: When is virtual inheritance a good design?

The problem here is that in C you have two interfaces I. That's why A :: x () satisfies its interface I - but it cannot make a non-abstract interface I'm from class B. For C, the only way to have exactly one interface is I - consists in changing B to get from me practically - in this way, both interfaces from A and from B will be merged with one in C. You cannot change B - so the only way is to add this redundant The code you are trying to avoid. I mean the definition of C :: X ().

+2
source

Your problem is with vtables. In your current code, you have two of them: one in A I and one in B I As long as only A actually inherits I , you can simply use regular inheritance and save overhead. If both actually inherited I , you would have only one instance of I in C , so only one vtable and A::X could really cover pure virual I::X

Given that you cannot change B , the only place you can take care of both vtables is C In my opinion, the path to what you mention is simply C::X redirects the call to A::X There is no code duplication, and it makes C not abstract:

 class C : public A, public B { public: virtual void X() { A::X(); } }; 

As for virtual inheritance, it is definitely here. But you may ask ...

+3
source

The only way I can imagine is to compose B* (or the smart version) in C instead of inheriting from it and forward the appropriate methods. You cannot do this while preserving inheritance, because the compiler does not know which chain of inheritance I should follow.

+1
source

Source: https://habr.com/ru/post/919884/


All Articles