class A { public: void eat(){ cout<<"A";} };
class B: virtual public A { public: void eat(){ cout<<"B";} };
class C: virtual public A { public: void eat(){ cout<<"C";} };
class D: public B,C { public: void eat(){ cout<<"D";} };
int main(){
A *a = new D();
a->eat();
}
I understand the diamond problem, and above piece of code does not have that problem.
How exactly does virtual inheritance solve the problem?
What I understand:
When I say A *a = new D();, the compiler wants to know if an object of type D can be assigned to a pointer of type A, but it has two paths that it can follow, but cannot decide by itself.
So, how does virtual inheritance resolve the issue (help compiler take the decision)?
You want: (Achievable with virtual inheritance)
And not: (What happens without virtual inheritance)
Virtual inheritance means that there will be only 1 instance of the base
Aclass not 2.Your type
Dwould have 2 vtable pointers (you can see them in the first diagram), one forBand one forCwho virtually inheritA.D‘s object size is increased because it stores 2 pointers now; however there is only oneAnow.So
B::AandC::Aare the same and so there can be no ambiguous calls fromD. If you don’t use virtual inheritance you have the second diagram above. And any call to a member of A then becomes ambiguous and you need to specify which path you want to take.Wikipedia has another good rundown and example here