12.6 — Constructor member initializer lists

In the previous lesson, for simplicity, we initialized our class member data in the constructor using the assignment operator. For example:

When the class’s constructor is executed, m_value1, m_value2, and m_value3 are created. Then the body of the constructor is run, where the member data variables are assigned values. This is similar to the flow of the following code in non-object-oriented C++:

While this is valid within the syntax of the C++ language, it does not exhibit good style (and may be less efficient than initialization).

However, as you have learned in previous lessons, some types of data (e.g. const and reference variables) must be initialized on the line they are declared. Consider the following example:

This produces code similar to the following:

Assigning values to const or reference member variables in the body of the constructor is clearly not possible in some cases.

Member initializer lists

To solve this problem, C++ provides a method for initializing class member variables (rather than assigning values to them after they are created) via a member initializer list (often called a “member initialization list”). Do not confuse these with the similarly named initializer list that we can use to assign values to arrays.

In lesson 1.4 -- Variable assignment and initialization, you learned that you could initialize variables in three ways: copy, direct, and via uniform initialization.

Using an initialization list is almost identical to doing direct initialization or uniform initialization.

This is something that is best learned by example. Revisiting our code that does assignments in the constructor body:

Now let’s write the same code using an initialization list:

This prints:

Something(1, 2.2, c)

The member initializer list is inserted after the constructor parameters. It begins with a colon (:), and then lists each variable to initialize along with the value for that variable separated by a comma.

Note that we no longer need to do the assignments in the constructor body, since the initializer list replaces that functionality. Also note that the initializer list does not end in a semicolon.

Of course, constructors are more useful when we allow the caller to pass in the initialization values:

This prints:

Something(1, 2.2, c)

Note that you can use default parameters to provide a default value in case the user didn’t pass one in.

Here’s an example of a class that has a const member variable:

This works because we’re allowed to initialize const variables (but not assign to them!).


Use member initializer lists to initialize your class member variables instead of assignment.

Initializing array members with member initializer lists

Consider a class with an array member:

Prior to C++11, you can only zero an array member via a member initialization list:

However, since C++11, you can fully initialize a member array using uniform initialization:

Initializing member variables that are classes

A member initialization list can also be used to initialize members that are classes.

This prints:

A 4
B 5

When variable b is constructed, the B(int) constructor is called with value 5. Before the body of the constructor executes, m_a is initialized, calling the A(int) constructor with value 4. This prints “A 4”. Then control returns back to the B constructor, and the body of the B constructor executes, printing “B 5”.

Formatting your initializer lists

C++ gives you a lot of flexibility in how to format your initializer lists, and it’s really up to you how you’d like to proceed. But here are some recommendations:

If the initializer list fits on the same line as the function name, then it’s fine to put everything on one line:

If the initializer list doesn’t fit on the same line as the function name, then it should go indented on the next line.

If all of the initializers don’t fit on a single line (or the initializers are non-trivial), then you can space them out, one per line:

Initializer list order

Perhaps surprisingly, variables in the initializer list are not initialized in the order that they are specified in the initializer list. Instead, they are initialized in the order in which they are declared in the class.

For best results, the following recommendations should be observed:
1) Don’t initialize member variables in such a way that they are dependent upon other member variables being initialized first (in other words, ensure your member variables will properly initialize even if the initialization ordering is different).
2) Initialize variables in the initializer list in the same order in which they are declared in your class. This isn’t strictly required so long as the prior recommendation has been followed, but your compiler may give you a warning if you don’t do so and you have all warnings turned on.


Member initializer lists allow us to initialize our members rather than assign values to them. This is the only way to initialize members that require values upon initialization, such as const or reference members, and it can be more performant than assigning values in the body of the constructor. Member initializer lists work both with fundamental types and members that are classes themselves.

Quiz time

Question #1

Write a class named RGBA that contains 4 member variables of type std::uint_fast8_t named m_red, m_green, m_blue, and m_alpha (#include cstdint to access type std::uint_fast8_t). Assign default values of 0 to m_red, m_green, and m_blue, and 255 to m_alpha. Create a constructor that uses a member initializer list that allows the user to initialize values for m_red, m_blue, m_green, and m_alpha. Include a print() function that outputs the value of the member variables.

If you need a reminder about how to use the fixed width integers, please review lesson 4.6 -- Fixed-width integers and size_t.

Hint: If your print() function isn’t working correctly, make sure you’re casting uint_fast8_t to an int.

The following code should run:

and produce the result:

r=0 g=127 b=127 a=255

Show Solution

12.7 -- Non-static member initialization
12.5 -- Constructors

297 comments to 12.6 — Constructor member initializer lists

  • Hassan

    Hi nascardriver,
    isn't the rule of thumb in the definition of function parameters is to use const reference whenever the parameter is a class and not expected to be modified?

    So in question#1 solution, shouldn't we define the RGBA constructor as:

    instead of:

    Or maybe I'm missing something here.

    • Alex

      using component_type = std::uint_fast8_t, which is a typedef of a fundamental type, not a class. So pass by const reference is not desired here.

  • Mahmoud

    you learned me in the previous lessons that you must initialize the constant variable and we do this initialization after the name of the variable directly like this

      but in the code below I compiled and run it and it works good with no errors, so how can this work coz I didn't initialize the constant variable, and generally i learned that you initialize the variable (const or non_const ) after the name of that variable but in OOP i wrote the definition of a variable in line and the initialization in another line, how can this happen???

    • Mahmoud

      Also i forgot to thank you to this great tutorial ♥♥♥.

    • nascardriver

      You've only defined a class, but didn't create any variables. The variables are created when you instantiate a `Ball`. When try try to do that, you'll find that it doesn't work, because `m_radius` must be initialized.

  • SuperNoob

    snippet 1:

    snippet 2:

    Are these two classes different in functionality? If so, which one is more efficient?

  • KR

    In an attempt to save some typing I tried to use:

    using num = static_cast<int>;

    It would not compile, giving me two errors:

    *expected a type specifier
    *syntax error: 'static_cast'

    does anybody know why this will not work and if anything can be done to make it work?

    • nascardriver

      `using` create type aliases, but `static_cast<int>` is not a type. The closest you can get is to write a function that takes a `component_type` and returns `int`.

  • kio

    Hi Alex and Nascardriver,

    Based on the rule:
    this is better

    than this:

  • goiu

    Hi there!
    Sorry for bad formatting, I just want to ask if it is compiler dependent or if I miss something: the output of this code is:
    x: -1 and y: -2 and last but not least, z: 3
    So, it seems like m_z has been 0-initialized, and I don't see why it should be that way...

    • nascardriver

      `B::B` has 1 parameter (line 19), but you're calling it with 3 arguments (Line 24), your code doesn't compile.

      • goiu

        Sorry, I think that I posted a mixed version of codes that I was experimenting on, however when I correctly pass one argument it exhibits the behavior I am talking about, that is it prints:
        x: -1 and y: -2 and last but not least, z: 3

        • nascardriver

          For future reference

          `m_z` is uninitialized when used to initialize `B::a`. Accessing uninitialized variables causes undefined behavior. Undefined behavior means anything can happen, including you observing a zero value.

          Try creating another `B` variable right before `b` and you'll likely get different results.

  • yeokaiwei

    3. Query on Member Initializer List
    How do I input things like RGBA blue?

    Based on the code above, there is already a default value of 0.

    Yet, if I leave a blank instead of a value (example below), a compiler error occurs.

    How do I get the compiler to accept a blank?

    • nascardriver

      There is no satisfying solution to this problem in C++. Some things you can try

      - Add public static member functions that create the `RGBA` with only some components
      - Add an aggregate, use that aggregate as the constructor's parameter, and use designated initialization to initialize the components you want. This is probably the easiest way to get the feeling of languages which do it properly without much effort. Requires C++20.
      - Use a builder-pattern to build an `RGBA`.
      - Overload the constructor. Will get confusing.

      There are other things you can try, but they don't get better.

      You can also try using libraries. boost has a feature for this. NamedType aims to solve exactly this problem.

  • yeokaiwei

    1. Quiz 1 RGBA

    I hope this is acceptable for Quiz 1.

  • Is there a benefit to using

    over something like

    if the ability to initialize the members with user input is not desired?

    EDIT: Nevermind, it's answered in the next lesson.

  • hisop

    If I inherit from another class that already has its member variables initialized, is it still best to use an initializer list in the child class or is it fine to just use assignment like so?

    • nascardriver

      The child can't directly initialize members of the parent class.
      `FighterProperties::FighterProperties` shouldn't initialize the members, they should be initialized at their declaration in the class.
      If you want children to be able to initialize the members of the parent, add a constructor with parameters for the members that the child needs to initialize, then have the child call that constructor.

  • Rosetastone

    >>Assigning values to const or reference member variables in the body of the constructor is clearly not sufficient in some cases.
    I think the statement above is not possible so it shouldn't be said, 'is clearly not sufficient in some cases' , it should be said, 'is clearly not possible'! Or maybe I am wrong but as far as I learned from this part, it isn't possible assigning values to cons and reference variables in the body of a constructor.

  • Ian

    I have a question.
    Why the code below does A constructor twice ?
    Thanks in advance!

    Output :
        A 0
        B 5
        A 4

  • fnamelname

    What's the reason to make [using component_type = ....] a public member? Is it just to expose it so we can see what the type is outside the class?

    • nascardriver

      That's right. Now the user of the class can safely use individual components. For example

  • Robbas

    Hi Nascar and Alex. I'd like to initialize the members directly inside the class rather than inside the constructor as parameters , how can I do it? If I remove the default parameter (255) of course I get an error because we don't have the 4th

    Error (active)    E0289    no instance of constructor "RGBA::RGBA" matches the argument list    

    But actually I have it as a default value inside the class.

    • nascardriver

      You can add another constructor that only initializes red, green, and blue

      Now `m_alpha` will get initialized with the value provided at its definition.

  • Gabe


  • Rae

    Never been happier figuring something out.  Here's my quiz code. (The sandbox stuff can be ignored, that's to separate playing with code from main()).

  • Ionut


    In the comment, did you actually mean "uniformly initialize" instead of "directly initialize"?

    Because here (as well as in chapter "1.4 -- Variable assignment and initialization"):

    you call using the braces "uniform initialization"

    Btw, DEFINITELY LOVE what you do and the way you organize the lessons and constantly keep updating them. Keep it up!

    One more question:

    • nascardriver

      "directly" wasn't referring to "direct initialization", but "immediately", "right away". I understand why this was confusing, I removed "directly".
      After editing a comment, code tags work after refreshing the page.

  • Al

    Is there a difference, either in the result or in the performance, between
    this implementation

    and this other one


    As always, thank you in advance.

    • nascardriver

      `MyClass2` might also result in an actual call to the constructor, whereas `MyClass` gets created with the correct values right away. This shouldn't bother you, there's no difference when you're compiling with optimizations.

  • ayaz

    thanks great explanation

    but what if we have to initialize an object array where at the object constructor you have to pass a parameter  
    class Average
       Average(int noOfPoints);
    class Math
       Average mA[2];
    #define LEN 2

    should it be done like above ?

    • nascardriver

      Don't use macros, use `constexpr`.
      You initialize arrays in the member initializer list as if you were initializing any other array

      This initializes each average with `LEN` as the `noOfPoints` parameter. That doesn't make sense, but I can't tell what else you were trying to do.

  • i love this site organized site for learning c++. Best and simplified explanation that i have ever seen.

Leave a Comment

Put all code inside code tags: [code]your code here[/code]