Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How direct base is constructed in virtual inheritance?

In the following code, I attempted to created a Leaf object obj to see the constructor order in multi-layer inheritance, but I find the structure of obj and constructor calls in this case a little strange.

#include<iostream>
using namespace std;
class Base1 { 
public:
    Base1(void) { 
        cout << "class Base1" << endl; 
    } 
}; 
class Base2 {
public: 
    Base2(void) { 
        cout << "class Base2" << endl; }
};
class Level1 : public Base2, virtual public Base1
{
public:
    Level1(void)
    {
        cout << "class Level1" << endl;
    }
};

class Level2 : public Base2, virtual public Base1
{
public:
    Level2(void)
    {
        cout << "class Level2" << endl;
    }
};

class Leaf :virtual public Level2, virtual public Level1
{
public:
    Leaf(void)
    {
        cout << "class Leaf" << endl;
    }
};


int main(void)
{
    Leaf obj;
    return 0;
}

With the output showing the constructor calls:

class Base1
class Base2
clase Level2
class Base2
class Level1
class Leaf

But the structure of obj at the end of the program is actually:

obj
--Level2
----Base2
----Base1
--Level1
----Base2
----Base1
--Base1

I know the Base1 of obj is virtual inherited, but during the construction of obj, Level2 and Level1 are also needed to be constructed, which leads to Base1 in each of their structure. But the whole construction process only calls Base1 constructor once. I cannot explain this. Does this mean the Base1 in Level2 and Level1 inside obj shares the same data with Base1 that directly belongs to obj?

like image 990
Kun Wu Avatar asked Apr 15 '16 13:04

Kun Wu


People also ask

What is virtual base class in inheritance?

Virtual base classes in C++ are used to prevent multiple instances of a given class from appearing in an inheritance hierarchy when using multiple inheritances.

How many copies of base class are created for virtual inheritance?

Virtual inheritance is a C++ technique that ensures only one copy of a base class's member variables are inherited by grandchild derived classes.

How is virtual inheritance implemented?

According to Wikipedia [1], “virtual inheritance is a technique used in C++, where a particular base class in an inheritance hierarchy is declared to share its member data instances with any other inclusions of that same base in further derived classes.”

What is virtual base class when do we make a class virtual?

In object-oriented programming, a virtual base class is a nested inner class whose functions and member variables can be overridden and redefined by subclasses of an outer class. Virtual classes are analogous to virtual functions.


2 Answers

But the whole construction process only calls Base1 constructor once. I cannot explain this.

The explanation is that Base1 is a virtual base of all the classes in the hierarchy. This is exactly what virtual bases are and what they're used for: sharing common base class instances.

Quotes from cppreference

For each distinct base class that is specified virtual, the most derived object contains only one base class subobject of that type, even if the class appears many times in the inheritance hierarchy (as long as it is inherited virtual every time).

All virtual base subobjects are initialized before any non-virtual base subobject, so only the most derived class calls the constructors of the virtual bases in its member initializer list:

Taking virtual inheritance into account, your structure diagram could be considered to be like this:

obj
--Level2
----Base2
----+-------Base1
--Level1   / /
----Base2 / /
----+----/ /
--+-------/

Does this mean the Base1 in Level2 and Level1 inside obj shares the same data with Base1 that directly belongs to obj?

Yes. There is exactly one Base1 instance within the entire structure of obj.

like image 179
eerorika Avatar answered Oct 31 '22 18:10

eerorika


Does this mean the Base1 in Level2 and Level1 inside obj shares the same data with Base1 that directly belongs to obj?

Yes, there's only one subobject of Base1, and shared by base subobject of Level2 and Level1 in class Leaf.

Here's an explanation with example from the standard, $10.1/6 Multiple base classes [class.mi] (emphasized mine)

For another example,

class V { /* ... */ };
class A : virtual public V { /* ... */ };
class B : virtual public V { /* ... */ };
class C : public A, public B { /* ... */ };

for an object c of class type C, a single subobject of type V is shared by every base subobject of c that has a virtual base class of type V. Given the class C defined above, an object of class C will have one subobject of class V, as shown below.

like image 39
songyuanyao Avatar answered Oct 31 '22 16:10

songyuanyao