Summary: In this tutorial, we will learn What is constructor initialization list in C++, how it differs from normal initialization and why we should use it in our C++ programs.

What is the Constructor Initialization list in C++?

Constructor Initialization List is an initialization method that happens before the execution of the constructor body.

The initialization list is written after the name of the constructor starting with the colon followed by the data members that need to be initialized.

class Student{
    public:
        Student() : name("Newton") {
            /* This initialization list works equivalent to:
                Student(){
                    this->name = "Newton";
                }
            */
        }
        
    private:
        std::string name;
};

The initialization list initializes the members without pre initializing them with empty or garbage values (which happens in normal initialization done inside the constructor).

This eliminates the extra work and improves the performance of the code.

When should we use the Constructor Initialization List?

There are many situations where the initialization of members inside of the constructor fails. In such case, we should use initialization list with constructors.

Here are some cases, where we must consider using Constructor Initialization list:

Example 1: Initializing const data members

By using the Constructor Initialization list, we can pass the values to the const data member of a class, which otherwise is not possible.

#include <iostream>
using namespace std;

class Student{
    private:
        const std::string name;
    public:
        Student(string n): name(n){
            /* This initialization list works equivalent to:
                Student(string name){
                    this->name = "name;
                }
            */
        }
};

int main(){
    Student std1("Newton");
}

Example 2: Providing arguments to the Parent Class’s Constructor

In inheritance, the execution of constructors happens from parents to child.

Thus we cannot pass arguments to the parent class’s constructor from the child class’s constructor, as it executes later in the execution order.

But, by using the Initializer list in the signature of the child class’s constructor, we can easily do so.

#include <iostream>
using namespace std;

class Person{
    public:
        //data member need to be initialized
        string name;
        
        //parent class's constructor
        Person(string name){
            this->name = name;
        }
};

class Student: public Person{
    public:
        //using initialization list to pass value to the parent
        Student(string name): Person(name) {}
};

int main(){
    Student std1("Newton");
}

Example 3: Initializing the Reference data members of the Class

The lvalue reference members (e.g. int &variable) of the class needs to be initialized with reference rather than a constant data value.

Initializing such reference member in the body of the constructor throws error:

class Person{
    public:
        //reference data member need to be initialized
        int &age;
        
        Person(int &a) {
            this->age = a;  //throws error
        }
};

In these cases, we can use the Initialization list to initialize the reference data members with the incoming reference.

#include <iostream>
using namespace std;

class Person{
    public:
        //reference data memeber need to be initialized
        int &age;
        
        Person(int &a) : age(a) {}
};

int main(){
    int myAge = 36;
    Person me(myAge);
    
    myAge++;
    cout << me.age;  //outputs 37
}

Like these three, there are multiple other cases where we can use the Constructor Initialization list to efficiently initialize the data member of the class.

Leave a Reply