The exact quote from the standard is 12.6.2p10:
In the constructor without delegation, initialization is performed in the following order:
- Firstly, and only for the constructor of the derived class itself (1.8), the virtual base classes are initialized in the order in which they appear at the first intersection from left to right from left to right of the acyclic graph base classes , where from left to right is the order in which the base classes appear classes in the base specifier-list of the derived class.
- Then direct base classes are initialized in the order of declaration, as they appear in the list of base qualifiers (regardless of the order of mem initializers).
- Then non-static data elements are initialized in the order in which they were declared in the class definition (again, regardless of the order of mem-initializers).
- Finally, the compound instruction of the constructor body is executed.
I believe the key is depth, first from left to right in a half-dead text. The class V1
is the virtual base X
, which is to the left of V2
, even if it is deeper in the hierarchy.
The hierarchy chart in your case looks like this:
X / \\ D1 D2 || / \\ V1 B3 V2 | / \ B1 B1* B2
In cases where single lines define ordinary inheritance, and double lines define virtual inheritance. Note that in your full object X
there are two instances of B1
. Now, if you perform a search in depth left-right, you will walk through the nodes in the following order:
[ B1, V1, D1, B3, B1*, B2, V2, D2, X ]
And the virtual bases V1
, V2
, D2
, which are the order of their construction. V1
requires construction B1
. V2
requires the construction of B1*
and B2
, D2
requires B3
, so the order should be:
[ B1, V1, B1*, B2, V2, B3, D2, D1, X ]
Where B1
build starts with V1
, B1*
and B2
must be ordered before V2
, B3
starts as a dependency on D2
. At this stage, all virtual databases are created and non-virtual databases begin to be built. The only non-virtual base X
that was not initialized due to the dependencies of the virtual databases is D1
.
If the diamond was closed (say that V1
and V2
inherited practically from B1
, then there will be only one instance of B1
, and it will be the first subobject to be built.