Multipath inheritance with only one base virtual

204 Views Asked by At

As far as i know, virtual ensures that only one copy of the properties of base class is inherited to the derived class. And in a multiple inheritance the constructor of all base is called first then the constructor of derived is called. In the following code why was the constructor of class B called twice in a row? To my understanding the output should have been

B
B1
B2
D

but the output came out to be

B
B
B1
B2
D

Here's the full code.

#include <iostream>

class B
{
public:
    B(){std::cout << "B" << std::endl;}
};

class B1:public B
{
public:
    B1(){std::cout << "B1" << std::endl;}
};

class B2:virtual public B
{
public:
    B2(){std::cout << "B2" << std::endl;}
};

class D:public B1, public B2
{
public:
    D(){std::cout << "D" << std::endl;}
};

int main()
{
    D d1;
}
3

There are 3 best solutions below

4
Julien BERNARD On

The inheritance of B by B1 must be virtual too.

Virtual inheritance doesn't mean "look in the rest of the hierarchy for an instance of inheritance of this class", it means "use only one instance of inheritance for all virtual inheritances in this hierarchy".

1
JimPri On

This is the classic "diamond problem" (described here). Your understanding of the virtual keyword is correct, but it only applies if you use it for both B1 and B2.

0
Mohammed Atik Choudhary On

Write your code like this:

#include <iostream>

class B
{
public:
    B(){std::cout << "B" << std::endl;}
};

class B1:public B
{
public:
    B1(){std::cout << "B1" << std::endl;}
};

class B2:public B1
{
public:
    B2(){std::cout << "B2" << std::endl;}
};

class D:public B2
{
public:
    D(){std::cout << "D" << std::endl;}
};

int main()
{
    D d1;
}