Member Initializer Lists

This lesson introduces Member Initializer Lists, focusing on their advantages for performance and readability, and how to use them effectively
This lesson is part of the course:

Intro to C++ Programming

Become a software engineer with C++. Starting from the basics, we guide you step by step along the way

Free, Unlimited Access
3D art showing a female blacksmith character
Ryan McCombe
Ryan McCombe
Updated

In previous lessons, we saw how we could initialize the members of our classes to different values, using a constructor:

class Character {
public:
  Character() {
    mHealth = 100;
  }

private:
  int mHealth;
};

C++ provides a dedicated syntax for this purpose, that we can use with constructors. This syntax is called a member initializer list.

Defining a Member Initializer List

The previous example, where we initialize our Health to 100 from the constructor, can be written using a member initializer list like this:

class Character {
public:
  Character() : mHealth{ 150 } {
    // Body here
  }

private:
  int mHealth;
};

We place the initializer list between the name and the body of the function, separated by a :.

We still can provide a function body for our constructor. It can be blank as in the above example, or we can put any other code in there that we want to run when our objects are first created.

If we do not need to provide a body, we still have to include the braces { and }.

Test your Knowledge

Using a Member Initialiser List

How can we update the following class to use a member initializer list?

class Weapon {
public:
  Weapon() {
    mDamage = 150;
  }

  int mDamage;
};

Why use a Member Initializer List?

Member initializer lists have three main advantages over writing equivalent code in the constructor body:

1. Performance

Due to nuance in how objects are constructed, initializing variables in a constructor body is slightly slower than it needs to be.

When our object is created, memory is assigned for its variables, and set to some default value before. This happens before our constructor body is executed.

If our constructor body then changes the value of those variables, we have to revisit and update those memory locations.

By specifying initial values in a dedicated initializer list, the compiler can identify and optimize that process to a single step.

2. Code Readability

Member initializer lists are dedicated to initializing our class members.

Once we get familiar with the syntax, we will immediately understand what that part of the code is doing when reading other files.

3. It’s Sometimes Required

In some scenarios, using a member initializer list is required to get the desired functionality. We’ll see an example of this in the next lesson, and more examples later in the course.

Initializing Multiple Members

Where we want to initialize multiple class variables, we can add those to the list, separated by commas:

class Character {
public:
  Character() : mHealth{ 150 }, mLevel{ 5 } {
    // Body here
  }

private:
  int mHealth;
  int mLevel;
};

Using Expressions in Member Initializer Lists

Like with the initialization of any other variables, any expression that results in a value of the correct type can be used.

This is shown in the below example. Remember, C++ is not especially sensitive to white space, so we can generally add line breaks and additional space where needed if we think it makes our code more readable:

int GetLevel() { return 5; }

class Character {
public:
  Character() :
    mHealth{ 100 + 50 },
    mLevel{ GetLevel() }
  {
    // Body here
  }

private:
  int mHealth;
  int mLevel;
};

Using Parameters in Member Initializer Lists

Of course, the above examples are slightly unnecessary. The previous examples don’t need an initializer list (or a constructor) at all - we could just do this:

class Character {
  int mHealth { 100 + 50 };
  int mLevel { GetLevel() };
};

However, the strength of initializing variables from constructors is that we can use parameters passed in by the code seeking to construct an object from our class:

Character SmallCharacter { 150, 5 };
Character BigCharacter { 300, 15 };

With member initializer lists, we can set our constructors up to support this as follows:

class Character {
public:
  Character(int Health, int Level) :
    mHealth{Health},
    mLevel{Level}
  {
    // Body here
  }

private:
  int mHealth;
  int mLevel;
};
Test your Knowledge

Using a Member Initialiser List

How can we update the following class to use a member initializer list?

class Weapon {
public:
  Weapon(int Damage) {
    mDamage = Damage;
  }

  int mDamage;
};

Summary

In this lesson, we explored the use of Member Initializer Lists. We learned that these lists offer a more efficient way to initialize class members, enhancing both performance and code readability. Key points include:

  • Member Initializer Lists allow for direct initialization of class members.
  • They provide performance benefits by reducing the number of operations during object creation.
  • These lists enhance code clarity, making the initialization intent explicit.
  • In certain scenarios, Member Initializer Lists are necessary for correct class functionality.
  • We can initialize multiple members and use expressions and constructor parameters in these lists.

Next Lesson: Working with Inherited Members

Next, we'll delve into working with inherited members in more depth.

This lesson will broaden our understanding of class inheritance in C++, focusing on how to effectively initialize and manipulate inherited class members. We'll cover:

  • Techniques for calling inherited constructors to ensure proper initialization of base class members.
  • Methods for modifying inherited variables, tailoring them to fit the needs of derived classes.
  • Strategies for replacing and extending inherited functions to add or alter functionality in derived classes.
  • Exploring the nuances and best practices of working with inheritance in C++.

Was this lesson useful?

Next Lesson

Working with Inherited Members

This lesson provides an in-depth exploration of using inherited methods and variables in C++, covering constructor calls, variable modification, and function shadowing
3D art of a man using a telescope
Ryan McCombe
Ryan McCombe
Updated
3D art showing a progammer setting up a development environment
This lesson is part of the course:

Intro to C++ Programming

Become a software engineer with C++. Starting from the basics, we guide you step by step along the way

Free, Unlimited Access
Inheritance
3D art showing a progammer setting up a development environment
This lesson is part of the course:

Intro to C++ Programming

Become a software engineer with C++. Starting from the basics, we guide you step by step along the way

Free, unlimited access

This course includes:

  • 56 Lessons
  • Over 200 Quiz Questions
  • 95% Positive Reviews
  • Regularly Updated
  • Help and FAQ
Next Lesson

Working with Inherited Members

This lesson provides an in-depth exploration of using inherited methods and variables in C++, covering constructor calls, variable modification, and function shadowing
3D art of a man using a telescope
Contact|Privacy Policy|Terms of Use
Copyright © 2024 - All Rights Reserved