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 ?
With the virtual inheritance a
D
object has a single base-classA
sub-object. This single sub-object can’t have two different implementations of a virtual function. In contrast, without virtual inheritance aD
object has two distinct base-classA
sub-objects, each with its own implementation of the function (which is OK until you try to call it on aD
object, at which point you need to indicate which one you want).Cheers & hth.
Your first scenario hierarchy corresponds to:
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:
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: