Initialization Lists in C++

When you first start using C++ you tend to set member variables with default values inside your constructor.

For example, you might have a class called Message that has three variables, and your constructor sets the default values like this:

    messageLength = 0;
    messageType = 0;
    messageBody = "Empty message";

This is acceptable and I’ve seen it in hundreds of classes, but there is a better way.

When setting member variables to their defaults, it can be more efficient to set them in an initialization list. You create this by adding a colon after the constructor name and listing the variables underneath separated by a comma. You set the default value by adding it in brackets, e.g.

Message::Message() :
    messageBody("Empty message")

In my opinion this also aids readability, since you are leaving the body of the constructor free to do ‘real’ construction work (if necessary), and you don’t have to hunt through lines of code to determine if and where a variable was set to a default value*.

Why is it more efficient?

Setting defaults in the body of the constructor uses assignment, whereas in the initialization list it uses initialization (you could have guessed from the name, right?).

If you are initializing classes (rather than built-in types, in which case this doesn’t apply), then using assignment means that behind the scenes you call the default constructor, followed by an assignment to set the variable. Putting the string variable in the initialization list means that you only call the copy constructor to set up the variable – so it costs one method call, not two.

The order matters

If you don’t enter the member variables in the initialization list in the same order as they appear in the header file (declaration), then gcc will prompt you with a warning:

warning: 'Message::MessageBody' will be initialized after
warning: 'int Message::MessageLength'
warning: when initialized here

Should you care about this warning?

I would argue that you should care about all warnings! It appears because it is possible that a member variable may rely on another member variable during initialization. For example, say your header contains the following:

int total;
int multiplier;

And you initialize them like this:

Constructor::Constructor() :
    total(multiplier * SOME_OTHER_VALUE)

This won’t work – total will be initialized first (no matter where you put it in your initialization list), because it is declared first in the header, so what will the value of multiplier be at this point? That depends on your compiler, but it almost certainly won’t be what you were expecting!

*Note that you can’t initialize the members of an array in a list – this must be done in the body of the constructor.