When Should You Use Member Initializer List in C++

When Should You Use Member Initializer List in C++

Are you still performing assignments in the body of the constructor? You are likely missing a lot in terms of powerful optimizations and safety that the member initializer list in C++ provides. They are advantageous for performance and ensure the correct initialization of const members, references, and non-default-constructible objects. Read this blog to see how this small change can render your code cleaner, safer, and faster!

Table of Contents:

What is the Member Initializer List in C++?

The member initializer list in C++ is a process to initialize the class members before the constructor body executes. It is assigned after the constructor’s parameter list and before the constructor’s body. It is declared by using a colon (:) followed by a comma-separated list of initializations. 

Example: 

Cpp

Output: 

member initializer list cpp

In the above code, if the object is created as a member initialized list(: name(n), age(a)) instead of assigning the values inside the constructor’s body, we already defined a person’s class with two data members: name and age, i.e., one is a string(name), and the other is an integer(age). 

In the main function, we create a Person object p1 with the name “Intellipaat” and age 25. These values are passed to the constructor and directly used to initialize the name and age members. The display() function then prints: Name: Intellipaat, Age: 25. Thus, this example shows a key aspect of object initialization in C++.

Member Initializer List Syntax in C++ (with Examples)

A member initializer list in C++ is used to initialize class members directly when a constructor is called, before the constructor body executes. This process is also known as object initialization in C++. The use of initializer lists in C++ is fundamental for efficient and correct object construction.

Member Initializer List Syntax in C++:

ClassName(Type1 arg1, Type2 arg2) : member1(arg1), member2(arg2) {
// constructor body
}
  1. ClassName is the name of the class and also the name of the constructor. It gets called when you create an object of the class.
  2. Inside the parentheses (Type1 arg1, Type2 arg2), you can define the values you want to pass when creating the object. These are the constructor’s parameters.
  3. The colon is the start of the member initializer list. This is where you directly give values to your class’s data members before the constructor body runs.
  4. member1(arg1) means you are initializing the class’s member variable member1 using the value of arg1.
  5. member2(arg2) does the same, means member2 gets its value from arg2.

Example 1:

class Book {
std::string title;
int pages;

public:
Book(std::string t, int p) : title(t), pages(p) {
std::cout << "Book created!n";
}
};

Explanation: In this class, the constructor takes a title and the number of pages as input. It uses the member initializer list to set the title and pages directly when the object is created. After that, it prints “Book created!” to show the constructor ran.

Example 2:

class Sample {
const int id;
int& ref;

public:
Sample(int x, int& r) : id(x), ref(r) {}
};

Explanation: In this class, id is a const int and ref is a reference to an int, so both must be initialized when the object is created. The constructor uses a member initializer list to directly set id with x and bind ref to r. This is the only correct way to initialize const and reference members in C++. Also, here, Sample(int x, int& r) is another example of a non-default constructor in C++.

Why and When to Use Member Initializer Lists in C++

Here are the points that describe why and when to use the member initializer list in C++:

1. Why Member Initializer Lists Are Required for const Members in C++

The data members of a const should be initialized at the time of object construction, and this initialization can only be done using an initializer list. The use of initializer lists in C++ becomes mandatory in such scenarios. Also, this is an important rule for const member initialization in C++.

Example:

Cpp

Output: 

member initializer - data members

In the above code, the test class t has an integer member that is const; these must be initialized using a member-initialized list (: t(t)). Because it’s impossible to modify the const members after the object creation. In the main function, the object t1 of the test is created with the value 10. Using the getT() function, we can print the value of t.   

2. Initializing Reference Data Members in C++ with Initializer Lists 

In C++, the reference members should be initialized only when the object is created, the same as the previous approach. The initialization can also be done using a member initializer list in C++. 

Example: 

Cpp

Output: 

member initializer - data members

In the above code, the class test has a reference member t. By using the member initialization list, the initialization can be done because the reference member must be bound during the object construction. In the main function, the object t1 is created with a reference to x, and the value of t is printed. First, it prints 20, and after modification, it prints 30.

Get 100% Hike!

Master Most in Demand Skills Now!

3. Using Initializer Lists for Objects Without Default Constructors

An initializer list is used when a class contains an object of another class that does not have a default constructor. This is important for proper object initialization in C++.

Example: 

Cpp

Output: 

member initializer - default constructor

In the above code, class B has a member object of class A, but class A does not have a default constructor. Instead, it has a non-default constructor in C++ program that takes an integer argument. Using the member initializer list, the a should be initialized in the B constructor. If an object of class B is created with 10, first it calls the A constructor for initialization. Only after constructing the object, the B constructor calls the message printed.

4. Initializing Base Class Members in Derived Classes Using Initializer Lists

In C++, the initializer list is required when a derived class has to initialize a base class using a parameterized constructor.

Example:

Cpp

Output: 

member initializer - default

In the above code, class B inherits from class A and uses the initializer list in the constructor to call the A constructor with the parameter x. If an object of B is assigned 10, it first initializes the base class A. After that, the message B constructor is called and printed. 

5. Avoid Naming Conflicts in Constructors with Member Initializer Lists

An initializer list is required in some cases, such as if a constructor parameter name is the same as the data member name.  

Example: 

Cpp

Output: 

member initializer -  class members

In the above code, class A has a data member i and uses the constructor initializer list(: i(i)) to initialize the i. The assigned constructor avoids naming conflicts that occur between the parameter i and the member variable i. In the main function, an object a from class A is assigned with value 10, and the getI() function is called to print the value, which is 10.

6. Performance Benefits of Using Member Initializer Lists in C++

To avoid unnecessary assignments inside the constructor body, we have to use an initializer list to make the code effective.

Example: 

Cpp

Output: 

member initializer - better performance

In the above code, through its constructor, the class Type has assigned an integer member value. The Myclass class contains a variable of type Type, and the constructor initializes the variable using a member initializer list. In the main function, a Type t1 with a value of 10 is assigned and passed to the Myclass constructor. The display () method is used to print the value of a variable that is 10. 

7. How Initializer Lists Improve Type Safety and Avoid Narrowing in C++

We should use uniform initialization({ }) with initializer lists to prevent unintended type conversions.

Example:

Cpp

Output: 

member initializer - type safety

The value 44 is passed to the base constructor in the above code, but 44 is outside the valid range for a char. This results in wrapping or truncating the value, i.e., narrowing conversion. This may cause unexpected behavior when printing. 

Initializer List vs Constructor Body

Aspect Initializer List Constructor Body
When it runs Before the constructor body After the initializer list is done
Used for Initializing member variables directly Running code and assigning values after initialization
Efficiency More efficient (initializes directly) Less efficient (initializes then assigns again)
Required for const, reference, and base class initialization Can’t be used for const or reference members
Syntax Followed by a colon: after the constructor declaration Inside the curly braces {} of the constructor
Order of execution Members are initialized in the order they are declared in the class Statements run in the order they appear inside {}
Example MyClass(int a) : value(a) {} MyClass(int a) { value = a; }

Common Mistakes with Member Initializer Lists in C++

Here are some common mistakes beginners make with member initializer lists in C++:

  • Wrong Order of Initialization: Even if you write members in a different order in the initializer list, they are always initialized in the order they are declared in the class. This can cause bugs if one member uses another during initialization.
  • Skipping Required Initialization: If a class has a const variable or a reference, it must be initialized using the initializer list in C++. You can’t assign values to them inside the constructor body, then this will give an error. This shows the importance of const member initialization in C++.
  • Using Assignment Instead of Initialization: Writing value = x; inside the constructor body works, but it’s less efficient than using [: value(x)] in the initializer list. It’s better to initialize the value directly.
  • Calling Functions Carelessly in the Initializer List: If you call a function or use a complex expression in the initializer list, it can cause problems, especially if that function depends on other members that aren’t initialized yet.
  • Forgetting to Use the Initializer List: Some people forget the use of initializer lists in C++, especially when working with const or reference members. This causes errors because such members must be initialized this way.
  • Not Understanding Default Initialization: If you don’t use an initializer list, member variables may be default-initialized. This can cause confusion or extra work for large objects or custom types.

Conclusion 

Using the member initializer list is effective and preferred because they make sure that there is proper object initialization in C++ of const members and references. The member initializer lists avoid the redundant default initialization and also improve performance by eliminating the extra assignments. And prevent unintended type conversions, which result in cleaner, safer, and more efficient code. 

You can learn more about C++ in the C++ programming language and also explore C++ Interview Questions prepared by industry experts.

When Should You Use Member Initializer List in C++ – FAQs

Q1. Why use an initializer list in C++?

To initialize class members efficiently and correctly, especially for const, references, and non-default-constructible types.

Q2. What advantages do initializer lists have compared to assignments in C++ constructors?

They prevent unnecessary default initialization and are thus faster and more efficient than assignments.

Q3. What is the use of initializer list in C++ when initializing class member variables?

The use of initializer list in C++ allows efficient initialization of class member variables before the constructor body executes.

Q4. How does the use of initializer lists promote type safety in C++?

 By guaranteeing initialization through {}, they avoid any unintended type conversions.

Q5. Do initializer lists affect the performance of C++ programs?

Yes, initialization lists decrease unnecessary constructor calls and assignments, thereby improving performance.

Q6. Can you initialize a const member in a constructor in C++?

Yes, but only using a member initializer list, const members cannot be assigned inside the constructor body.

Q7. how to avoid default constructor errors in C++?

Define a default constructor explicitly or ensure all members have default initializers to avoid default constructor errors.

Q8. Does initializer list improve performance in C++?

Yes, initializer lists improve performance by directly initializing members instead of assigning values after default construction.

Q9. What is object initialization in C++?

Object initialization in C++ is the process of assigning initial values to an object’s data members when it is created.

Q10. What is a non-default constructor in C++?

A non-default constructor in C++ is a constructor that takes one or more arguments to initialize an object.

About the Author

Technical Research Analyst - Full Stack Development

Kislay is a Technical Research Analyst and Full Stack Developer with expertise in crafting Mobile applications from inception to deployment. Proficient in Android development, IOS development, HTML, CSS, JavaScript, React, Angular, MySQL, and MongoDB, he’s committed to enhancing user experiences through intuitive websites and advanced mobile applications.

Full Stack Developer Course Banner