I wrote this program with virtual inheritance and I have a few questions.
#include<iostream>
using namespace std;
class B1
{
public:
B1()
{
cout << "In B1 constructor\n";
}
};
class V1 : public B1
{
public:
V1()
{
cout << "In V1 constructor\n";
}
};
class D1 : virtual public V1
{
public:
D1()
{
cout << "In D1 constructor\n";
}
};
class B2
{
public:
B2()
{
cout << "In B2 constructor\n";
}
};
class B3 {
public:
B3()
{
cout << "In B3 constructor\n";
}
};
class V2 : public B1, public B2
{
public:
V2()
{
cout << "In V2 constructor\n";
}
};
class D2 : public B3, virtual public V2
{
public:
D2()
{
cout << "In D2 constructor\n";
}
};
class X : public D1, virtual public D2
{
public:
X()
{
cout << "In X constructor\n";
}
};
int main()
{
X x;
return 0;
}
Output of the program:
In B1 constructor
In V1 constructor
In B1 constructor
In B2 constructor
In V2 constructor
In B3 constructor
In D2 constructor
In D1 constructor
In X constructor
I expected an output like this:
In B1 constructor
In B2 constructor
In V2 constructor
In B2 constructor
In D2 constructor
In B1 constructor
In V1 constructor
In D1 constructor
In X constructor
on the basis that an object of a virtual base class is constructed first and then the other base class object. Can Someone explain this behaviour?
The exact quote from the standard is 12.6.2p10:
I believe the key is the depth-first left to right in the bolded text. The
V1class is a virtual base ofXthat is to the left ofV2, even if it is deeper in the hierarchy.The hierarchy graph in your case is like:
Where single lines identify plain inheritance, and double lines are virtual inheritance. Note that there are two instances of
B1in your complete objectX. Now if you perform a depth-first left-to-right search you will walk the nodes in the following order:And the virtual bases are
V1,V2,D2, which is the order in which they will be constructed.V1requires the construction ofB1.V2requires the construction ofB1*andB2,D2requiresB3, so the order should be:Where
B1construction is triggered byV1,B1*andB2must be ordered beforeV2,B3is triggered as a dependency ofD2. At this point all of the virtual bases are built and the non-virtual bases start to be constructed. The only non-virtual base ofXthat has not been initialized due to the dependencies of the virtual bases isD1.If the diamond was closed (say that
V1andV2inherited virtually fromB1, then there would be only one instance ofB1and it would be the first subobject to be constructed.