Virtual inheritance to solve diamond problem

Onur Uzun
1 min readApr 24, 2018

You want: (Achievable with virtual inheritance)

  A  
/ \
B C
\ /
D

And not: (What happens without virtual inheritance)

A   A  
| |
B C
\ /
D

Virtual inheritance means that there will be only 1 instance of the base A class not 2.

Your type D would have 2 vtable pointers (you can see them in the first diagram), one for B and one for C who virtually inherit A. D's object size is increased because it stores 2 pointers now; however there is only one A now.

So B::A and C::A are the same and so there can be no ambiguous calls from D. 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.

Problematic:

struct Animal {
virtual ~Animal() { }
virtual void eat();
};

struct Mammal : Animal {
virtual void breathe();
};

struct WingedAnimal : Animal {
virtual void flap();
};

// A bat is a winged mammal
struct Bat : Mammal, WingedAnimal {
};

Bat bat;

Solution:

struct Animal {
virtual ~Animal() { }
virtual void eat();
};

// Two classes virtually inheriting Animal:
struct Mammal : virtual Animal {
virtual void breathe();
};

struct WingedAnimal : virtual Animal {
virtual void flap();
};

// A bat is still a winged mammal
struct Bat : Mammal, WingedAnimal {
};

--

--