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 simply add virtual
to the inheritance of I
for B
, then A::X()
resolves I::X()
in C
.
However, I cannot change the source of B
.
My question: Can I get A::X()
to resolve I::X
for C
without being able to change B
? I have tried declaring A
and B
to be virtual to C
to no avail. I am trying to have no redundant code (e.g. have C declare X() { A::X(); }). Any neat hacks?
Also - there are a few questions very much like this, but I couldn't find any talking about using virtual
inheritance. Please point to me one if I missed it.
Multiple inheritance Inheritance is another feature of object-oriented programming where a particular class can derive from a base class. Multiple inheritance allows the extension of more than one base class in a derived class. Abstract classes do not support multiple inheritance.
A class can extend at most one abstract class, but may implement many interfaces. That is, Java supports a limited form of multiple inheritance.
As we have explained in the inheritance chapter, multiple inheritance is not supported in the case of class because of ambiguity. However, it is supported in case of an interface because there is no ambiguity. It is because its implementation is provided by the implementation class.
Your problem is with the vtables. In your current code, you have two of them - one in A
's I
and one in B
's I
. As long as only A
virtually inherits I
, you could just as well use regular inheritance and save the overhead. If both virtually inherited I
you'd have only one instance of I
in C
, therefore only one vtable, and A::X
could indeed cover the pure virual I::X
.
Given you can't change B
, the only place you can take care of both vtables is C
. In my opinion, the way to go is what you mention - just have C::X
forward the call to A::X
. There's no code duplication there, and it makes C
non-abstract:
class C : public A, public B {
public:
virtual void X() { A::X(); }
};
As for virtual inheritance, there definitively have been some here. But you're welcome to ask...
This is quite good: When virtual inheritance IS a good design?
The problem here is that in C you have two interfaces I. That is why A::x() satisfies its interface I - but it cannot make not abstract interface I from class B. For C the only way to have exactly one interface of I - is to change B to derive from I virtually - in this way both I interfaces from A and from B will be merged to one in C. You cannot change B - so the only way is to add this redundant code which you are trying to avoid. I mean define C::X().
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With