Are multiple-inherited constructors called multiple times?
The order of constructor calls for your inheritance hierarchy will be:
Base()
DerivedBaseTwo()
Base()
DerivedBaseOne()
Derived()
The order is indeed well-defined and depends on the order in which you mention the derivation for base classes and the order in which you declare members in the class for members. (See the reference from the C++ Standard below.)
Does the Base() constructor get called twice?
YES
The Base()
class constructor gets called here twice, because two classes DerivedBaseTwo()
and DerivedBaseOne()
derive from it, so the base class constructor gets called once for each of them. Your Derived
class has two distinct Base
subobjects through multiple paths (one through DerivedBaseOne()
and the other though DerivedBaseTwo()
).
The hierarchy of classes you have with multiple inheritance is unusual and it leads to a problem called the Diamond Shaped Inheritance Problem. To avoid this problem C++ introduces the concept of Virtual base class.
Reference:
C++03 Standard: 12.6.2/5, Initializing bases and members
Initialization shall proceed in the following order:
— First, and only for the constructor of the most derived class as described below, virtual base classes shall be initialized in the order they appear on a depth-first left-to-right traversal of the directed acyclic graph of base classes, where “left-to-right” is the order of appearance of the base class names in the derived class base-specifier-list.
— Then, direct base classes shall be initialized in declaration order as they appear in the base-specifier-list (regardless of the order of the mem-initializers).
— Then, nonstatic data members shall be initialized in the order they were declared in the class definition (again regardless of the order of the mem-initializers).
— Finally, the body of the constructor is executed.
The way you write it, Derived
has two distinct subobjects of type Base
, and each gets their own constructor called from the respective DerivedBaseXXX
constructor of which it is the subobject. The order of calls follows the order of declaration.
By contrast, of you declare DerivedBaseXXX : virtual public Base
, then there is only one Base
subobject, and its constructor is called from the most derived object, i.e. from the Derived
object.
(To explain in a bit more detail: A (possibly singly-inheriting) class is constructed by first 1) calling the base class's constructor, then 2) calling the constructors of all member objects in their order of declaration, and finally 3) executing the constructor function body. This applies recursively, and for multiple inheritance, you just replace (1) by calling all the base class's constructors in the order in which the inheritance was declared. Only virtual inheritance adds a genuine extra layer of complication here.)
This is answered in: http://www.parashift.com/c++-faq-lite/multiple-inheritance.html#faq-25.14
The very first constructors to be executed are the virtual base classes anywhere in the hierarchy. They are executed in the order they appear in a depth-first left-to-right traversal of the graph of base classes, where left to right refer to the order of appearance of base class names.
Since your multiple inheritance declaration lists DerivedBaseTwo
first, its construction order will be executed before DerivedBaseOne
's.
So in your Derived
class, DerivedBaseTwo
and its chain is created first, that is:
1 - Base
then DerivedBaseTwo
And then DerivedBaseOne
and its chain:
2 - Base
then DerivedBaseOne
And then:
3 - Derived
is created after everything else.
Also, with multiple inheritance be mindful of the Diamond Inheritance Problem