Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Order of calling base class constructor from derived class initialization list

struct B { 
  int b1, b2;  
  B(int, int);
};

struct D : B {
  int d1, d2;
// which is technically better ?
  D (int i, int j, int k, int l) : B(i,j), d1(k), d2(l) {} // 1st Base
// or
  D (int i, int j, int k, int l) : d1(k), d2(l), B(i,j) {} // last Base
};

Above is just a pseudo code. In actual, I wanted to know that does the order of calling base constructor matter?

Are there any bad behaviors (especially corner cases) caused by any of the cases? My question is on more technical aspect and not on coding styles.

like image 653
iammilind Avatar asked Jun 06 '11 03:06

iammilind


People also ask

What is the order of execution of base class constructor?

Constructors of Virtual base classes are executed, in the order that they appear in the base list. Constructors of nonvirtual base classes are executed, in the declaration order. Constructors of class members are executed in the declaration order (regardless of their order in the initialization list).

Is base or derived constructor called first?

Base Constructor is called first. But the initializer of fields in derived class is called first.

In which order the constructors of derived classes are called?

For multiple inheritance order of constructor call is, the base class's constructors are called in the order of inheritance and then the derived class's constructor.

How do you call a base class constructor from a derived class?

We have to call constructor from another constructor. It is also known as constructor chaining. When we have to call same class constructor from another constructor then we use this keyword. In addition, when we have to call base class constructor from derived class then we use base keyword.


1 Answers

The order you refer in your question is not the "order of calling base constructor". In fact, you can't call a constructor. Constructors are not callable by the user. Only compiler can call constructors.

What you can do is to specify initializers. In this case (constructor initializer list) you are specifying initializers for subobjects of some larger object. The order in which you specify these initializers does not matter: the compiler will call the constructors in a very specific order defined by the language specification, regardless of the order in which you specify the initializers. The base class constructors are always called first (in the order in which the base classes are listed in class definition), then the constructors of member subobjects are called (again, in the order in which these members are listed in the class definition).

(There are some peculiarities in this rule when it comes to virtual base classes, but I decided not to include them here.)

As for the bad behaviors... Of course there is a potential for "bad behaviors" here. If you assume that the order of initialization depends on the order you used in the constructor initializer list, you will most likely eventually run into an unpleasant surprise, when you discover that the compiler completely ignores that order and uses its own order (the order of declaration) instead. For example, the author of this code

struct S {
  int b, a;
  S() : a(5), b(a) {}
};

might expect a to be initialized first, and b to receive the initial value of 5 from a, but in reality this won't happen since b is initialized before a.

like image 154
AnT Avatar answered Sep 22 '22 10:09

AnT