What is a constructor initialization list?

1 answer

Answer

1060516

2026-05-17 22:35

+ Follow

The constructor initialisation list is the most efficient method of initialising class members, including primitive members. You use it always and without exception to ensure efficient construction.

Consider the following:

class foo

{

int m_data;

public:

foo(int data=0){ m_data=data; }

foo(const foo& f){ m_data=f.m_data; }

};

This class employs inefficient construction technique by initialising the member variables in the constructor bodies rather than the initialisation list. In other Words, m_data is instantiated and initialised in two stages instead of one. It is not unlike the following two stage initialisation:

int m_data;

m_data =0;

A more efficient way of writing these lines is to initialise at the point of instantiation using a compound statement:

int m_data=0;

The same applies to class construction. By using the initialisation list, member variables are initialised at the point of instantiation, as per the following:

class foo

{

int m_data;

public:

foo(int data=0):m_data(data) {}

foo(const foo& f):m_data(f.m_data) {}

};

You will note that primitive members use object-oriented syntax in the initialisation list. This is not merely sugar-coating -- it applies to all members, including base classes. This makes it possible to invoke specific base class constructors, rather than the default constructor that would be implicitly invoked (or the base class copy constructor in the case of a derived class copy constructor).

Consider the following:

class base

{

int m_data;

public:

base(int data=0):m_data(data) {}

base(const base& b):m_data(b.m_data) {}

};

class derived : public base

{

public:

derived(int data=0):base(data) {}

derived(const derived& d):base(d) {}

};

Note how the derived class default constructor invokes the base class default constructor, but passes the data argument to it. Had you not used the initialisation list you'd have to construct base, then derived, and then initialise the base class member via a setter. Clearly the initialisation list is more efficient because the base class can be initialised before derived is even instantiated, which cannot happen until the base class is fully-instantiated.

Note also that the copy constructor specifically invokes the base class copy constructor. Although the argument, d, is not a base class, it is a type of base class, thus there is no need to upcast the argument.

Ultimately, it can be seen that the constructor bodies are largely redundant. You still need a constructor body, even an empty one, but most of the time you will use the body for debug trace code. There will be times, however, where the class initialisation list cannot fully initialise a member because one or more arguments require more complex processing (such as calling a complex setter). In this case, you must use the constructor body. However, you must still perform as much initialisation as is possible via the initialisation list to ensure the most efficient construction method. Only those members that require additional processing need not be initialised, but it costs nothing to initialise them to an arbitrary or default value.

The initialisation list is vital in the case of the copy constructor, as passing an object to a function by value will automatically invoke the copy constructor. If any member variables are embedded objects, or the object is derived from one or more base classes, then their copy constructors will be invoked as well. Therefore it pays to make construction as efficient as possible when copying objects. However, the same applies to any constructor. The more efficient the constructor performs, the better your programs will perform, especially in complex hierarchies where objects may be deeply embedded within other objects that are themselves embedded.

ReportLike(0ShareFavorite

Copyright © 2026 eLLeNow.com All Rights Reserved.