Given the following code (without virtual inheritance) :
class A
{
public:
virtual void f() = 0;
};
class B : public A
{
public:
virtual void f() {}
};
class C : public A
{
public:
virtual void f() {}
};
class D : public B, public C
{
/* some code */
};
int main()
{
D d;
return 0;
}
the code compile.
On the other hand , here :
class A
{
public:
virtual void f() = 0;
};
class B : virtual public A
{
virtual void f() {}
};
class C : virtual public A
{
virtual void f() {}
};
class D : public B, public C
{
/* some code */
};
int main()
{
D d;
return 0;
}
The compiler presents a compilation error:
no unique final overrider for 'virtual void A::f()' in 'D' .
Why is it different in the second code ?
The "diamond problem" (sometimes referred to as the "Deadly Diamond of Death") is an ambiguity that arises when two classes B and C inherit from A, and class D inherits from both B and C.
Virtual inheritance solves the classic “Diamond Problem”. It ensures that the child class gets only a single instance of the common base class. In other words, the Snake class will have only one instance of the LivingThing class. The Animal and Reptile classes share this instance.
The diamond problem The diamond problem occurs when two superclasses of a class have a common base class. For example, in the following diagram, the TA class gets two copies of all attributes of Person class, this causes ambiguities. For example, consider the following program. CPP.
C++ allows a special kind of inheritance known as multiple inheritance. While most object oriented languages support inheritance, not all of them support multiple inheritance. (Java is one such example). Multiple Inheritance simply means that a class can inherit properties from more than one base class.
Your first scenario hierarchy corresponds to:
F() F()
A A
| |
F() B C F()
\ /
D
Where D is not abstract, because there are two A subobjects in an object of type D: One that is made concrete by B through the lattice of B, and another that is made concrete through the lattice of C.
Unless you try to invoke the function F() on object of D there will not be any ambiguity.
Your second scenario hierarchy corresponds to:
F()
A
/ \
F() B C F()
\ /
D
In this scenario, the object D has a single Base class A sub object, and it must override and provide implementation of the pure virtual function in that subobject.
Herb Sutter's articles in Guru Of The Week(GOTW) are a nice read for Multiple Inheritance:
With the virtual inheritance a D
object has a single base-class A
sub-object. This single sub-object can’t have two different implementations of a virtual function. In contrast, without virtual inheritance a D
object has two distinct base-class A
sub-objects, each with its own implementation of the function (which is OK until you try to call it on a D
object, at which point you need to indicate which one you want).
Cheers & hth.
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