Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Are multiple-inherited constructors called multiple times?

Tags:

Are multiple-inherited constructors called multiple times? And in what order are constructors called? Does this depend on the order in the inheritance list?

Here is an example (it's only for making the situation clear, no real-life example).

class Base {};
class DerivedBaseOne : public Base {};
class DerivedBaseTwo : public Base {};
class Derived : public DerivedBaseTwo, public DerivedBaseOne 
{};

//somewhere in the code, is Base() called two times here?
Derived * foo = new Derived();

Is the Base() constructor called twice? And in what order are the constructors called? Base first? Or DerivedBaseOne() or DerivedBaseTwo() first?

like image 966
blubberbernd Avatar asked Sep 13 '11 17:09

blubberbernd


People also ask

How are constructors called in multiple inheritance?

Constructor is automatically called when the object is created. Multiple Inheritance: Multiple Inheritance is a feature of C++ where a class can derive from several(two or more) base classes. The constructors of inherited classes are called in the same order in which they are inherited.

What is multiple inheritance inheritance?

Multiple inheritance is a feature of some object-oriented computer programming languages in which an object or class can inherit features from more than one parent object or parent class. It is distinct from single inheritance, where an object or class may only inherit from one particular object or class.

How are constructors used in inheritance?

When classes are inherited, the constructors are called in the same order as the classes are inherited. If we have a base class and one derived class that inherits this base class, then the base class constructor (whether default or parameterized) will be called first followed by the derived class constructor.

How constructors are called in inheritance in Java?

Answer: Order of execution of constructors in inheritance relationship is from base /parent class to derived / child class. We know that when we create an object of a class then the constructors get called automatically.


2 Answers

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.

like image 157
Alok Save Avatar answered Oct 10 '22 04:10

Alok Save


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.)

like image 41
Kerrek SB Avatar answered Oct 10 '22 06:10

Kerrek SB