Does this still solve the diamond problem?
class A
{};
class B : virtual A
{};
class C : A
{};
class D : B, C
{};
Edit: If not, what is it then? Is it the same as this?
class A
{};
class B : A
{};
class C : A
{};
class D : B, C
{};
Or is it something even else?
Diamond problem and ambiguous call to common base members can be best described through the following pictorial equivalent which also give an insight of the memory model
class A
{void foo(){};};
class B :public A
{};
class C :public A
{};
class D :public B,public C
{};
Since Inheritance simply puts the implementation of two objects one after another, all methods of Base class A gets duplicated in derived class B and C, which has an equivalent pictorial representation as
A A
| |
| |
B C
\ /
\ /
D
class A
{};
class B :public virtual A
{};
class C :public A
{};
class D :public B,public C
{};
With the virtual keyword, compiler generates a vtable for Derived class B with a vptr (virtual pointer) in the vtable of B which stores an Offset of the Base class A. For C, it still copies all method of base class A. So class D, via Base class B refers the members of base class A via a vptr where are Class C refers the members of base class A as a duplicate copy. So the diamond problem and ambiguity still persist.
A A
/ |
/ |
B C
\ /
\ /
D
class A
{};
class B :public virtual A
{};
class C :public virtual A
{};
class D :public B,public C
{};
Now when both the derived classes B and C inherits A virtually, Compiler creates a Vtable for both B and C and creates a vptr in each of its vtable to refer the offset of the Base Class A. This finally solves the Diamond Problem as there is only one copy visible via B or C
A
/ \
/ \
B C
\ /
\ /
D