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
?
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.
Virtual inheritance is a C++ technique that ensures only one copy of a base class's member variables are inherited by grandchild derived classes.
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.”
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.
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
.
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 typeC
, a single subobject of typeV
is shared by every base subobject ofc
that has a virtual base class of typeV
. Given the classC
defined above, an object of classC
will have one subobject of classV
, as shown below.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With