8.5a — 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

8.5b -- Non-static member initialization
8.5 -- Constructors

269 comments to 8.5a — Constructor member initializer lists

  • Kwonk

    In the tutorial about vectors you said that if you initialize a vector with braces, you create it with an initializer list; and if you create it with direct initialisation, there is one parameter representing the vector's length.

    Are these rules the same when you're initializing a vector in a member initialization list?

  • AbraxasKnister

    What shall I best do when I have a member that I don't want to modify with a value that is runtime dependent? I've come up with the following:

    Is there a way to do that better? Do I really have to make the Space::state typedef public?

    • nascardriver

      In your example, `state` should be public, because you're exposing it to the outside via `iniZero`. The outside can still use `iniZero`, but storing the return value can get messy.

      Out-of-class member definitions can access private members, because even though they're outside of the class, they're still members.

      You can make `state` private (but shouldn't) and your code would still work.

  • Sam


  • Miroslav Avramov

    #include <iostream>
    #include <sstream>
    #include <string>

    using namespace std;
    void test();
    string myItoa(int val);

    string myItoa(int val){
        stringstream ss;
        cout<< "val = "<<val<< endl;
        ss << val;
        return ss.str();

    class A{
        void print();
        string::size_type strLen_;
        string str_;
        int a_;

    void A::print(){
    cout << "a = " << a_ << ", str = " << str_ << ", strLen = "<< strLen_<< endl;


    void test(){
        A a;

    int main(void){
        return 0;
    Why I receive on console a = 10, str = 1, strLen = 145268932506861

    • nascardriver

      Members are initialized in the order of the declaration in the class. The order in the member initializer list doesn't matter. Your compiler should have warned you about this. Make sure you set up compiler warnings as shown in chapter 0.

  • Christopher Springer

    I'll apologize in advance if this topic is discussed somewhere else...

    It seems to me this chapter (or somewhere close) would be a great place to introduce using typedefs and/or the "using" directive to create a type alias in your class.  The complexity and amount of typing required to complete the quiz question in this chapter may warrant something like the following:

    I found myself wondering about the scope of the using directive with classes as well.  For example, what is the proper way to use typedef/using to make sure consumers of the class can use that type as well?  Also, how/where should I declare the typedef/using if I want to hide it from anything outside my class.  I'm not sure if this should be discussed in a separate chapter or here but it would be useful information.


    • nascardriver

      I added a section to lesson 8.2, showing that type aliases can be defined inside classes.
      Type alias members follow the same access rules as variables and functions. They can be private, protected, or public.

  • Tushar Roy

    What if I want to initialize y with initializer list?

    • nascardriver

      Is this what you mean?

      • Tushar Roy

        Intializing "y" in class B.

  • Gutemberg Araújo

    Hi Alex && NascarDriver,

    i'm trying to make a list with a class link this:

    When compiling i'm getting the following error:

    ||=== Build: Debug in SPP (compiler: GNU GCC Compiler) ===|
    include\stock.h|5|error: 'class Stock' has pointer data members [-Werror=effc++]|
    include\stock.h|5|error:   but does not override 'Stock(const Stock&)' [-Werror=effc++]|
    include\stock.h|5|error:   or 'operator=(const Stock&)' [-Werror=effc++]|

    I searched that this error is related with COPY and MOVE constructors, but i didn't understand it at all.
    Could you help me to understand this, pls?
    Thanks in advance.

    Happy New Year for you all Guys that always Save Our Souls (S.O.S.) !!!

    • nascardriver

      Your code will cause problems if `next` is dynamically allocated. If it is, you need custom handling for copies (Next chapter).
      If `next` is not dynamically allocated, you can stop treating that warning as an error by adding

      to your compile options. (Or disable Treat Warnings As Errors in your project settings until you know how to fix it).

  • Ged

    1. Is commenting like that a viable option if we need to divide a line?

    2. Our constructor's { } brackets will always have last priority versus initialization?

    • nascardriver

      1. Your lines shouldn't exceed 80 characters. Comments at the end of a line often exceed this limit. Move them into their own line. The lesson uses comments at the end of the line because it has to refer to that exact line. Moving them would be confusing.

      2. I don't understand the question. Can you provide an example or elaborate?

      • Ged

        In this line of code std::cout is in the brackets with constructor B(int y), but it is executed the last. So do constructors ignore everything in their brackets until all the other constructors are executed? Let's say we have a class in a class in a class an so on. And lets say all of them had the same code and a variable in which to execute it. 1st class value would 4, then 2nd class value would be 3 and so on. Would std::cout only be executed after all the constructors have finished initializing values? If this is the case in what order std::cout would be executed I understand (stack).

        • nascardriver

          Members are initialized before the constructor body is executed. There will be more initializations in the future, but the constructor body will continue to be last.

  • Manoj EN

    how to Initialize member variables that are array of classes

  • hellmet

    How about this?

    Doesn't seem to be mentioned

  • sito

    hello! this is a great site and I've learned much from it as a student.
    Now my question. So when you're converting a member variable to another type in a class. Instead of converting while you're printing as i did when solving the quiz in this lesson. Wouldn't the correct thing be to make a function that converts the member variables and then returns them? if that's the case would it be correct to call that function in the class?

    • I'm assuming by "converting" you mean "casting".

      > Wouldn't the correct thing be to make a function that converts the member variables and then returns them?
      No. The author of the class can't know to what types the caller wants to convert the members. Adding functions for every common type is way too much work. This is what casts are there for.

      If you meant conversions to other color representations (rgba, argb, hsl, ...), then yes, those should be added as member functions.

  • Parsa

    Why do the member variables need to be casted to an int? (quiz)

  • x-ray

    As Winchester already mentioned, the following statement is not correct (anymore?): "In lesson 4.1 -- Introduction to fundamental data types, you learned that you could initialize variables in three ways: copy, direct, and via uniform initialization (C++11 only)." This is now in 1.4 — Variable assignment and initialization.

  • Samira Ferdi

    Hi, Alex and Nascardriver!

    > 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).

    What's mean of  " ensure your member variables will properly initialize even if the initialization ordering is different"? In fundamental type I understand the meaning, but in class member variable?

    • Line 24 causes undefined behavior. Members are initialized in the order of their declaration. The order in the member initializer list is irrelevant. `m_arrData` was initialized first. When it was initialized, `m_iLength` was still `0`.

      • Samira Ferdi

        Thank you, Nascardriver!
        I understand the idea of members are initialized (in the initializer list) in the order of their declaration.

        But, the statement "ensure your member variables will properly initialize even if the initialization ordering is different" that Alex said in my mind is like our initialization has nothing to do with the ordering of the declaration of the variables. In non-class variable I understand the meaning of that statement (because the initialization has nothing to do with declaration ordering). So, it makes me think how to initialize class member variables that independent with members declaration order. So, if this thing that I should do, how can I do it?

        • You should write your code such that the order of declaration doesn't matter. The code I wrote above shouldn't use `m_iLength` to initialize, even if line 4 and 5 were swapped. The constructor should be

          That way the order of declaration can't break the initialization.

  • Alexsander


    First of all, I would like to say that I'm pretty addicted to this site. C++ is awesome!
    I've noted that, in Summary, it is written that the initializer list is the only way to initialize member variables thats require values upon initialization. I think that there's one more way to do that: initilializing the member variables at the place where they are declared, like this example:

    class Box {
      int items = 3;
      Box () {}

    Please correct me if it's wrong.

  • vegan cat

    Hi! I tried to put the class in a header file and run into problems - there is an error in my constructor definition. The compiler complains that it wants a semicolon instead of a comma after "int8 red = 0" (i used my own typedef instead of the one requested thinking it would solve the problem - it didn't). Also, I get the feeling that including iostream in a header file is bad and could screw up my program - am I even allowed to do this? How would one define a class like that in a header file? Does it even make sense?

    • RGBA is a preprocessor definition (Line 2), you can't re-use it. Change the name of the header guard or class to fix the problem.

      > including iostream in a header
      Include as few other headers in a header as possible.
      Move the definitions of `RGBA::RGBA` and `RGBA::print` into a source file, then you don't need <iostream> in the header anymore.

      > am I even allowed to do this?
      Yes, but it should be avoided as it can lead to circular includes, name conflicts, and slower compilation.

      > Does it even make sense?
      Yes, you should put classes into headers.

  • Jan Perme

    Anyone has a clue, why this initialization of pointers in Facade class works ? Thanks.

  • Torraturd

    Hi, I'm just wondering if it is an issue if i declare my variables like this:

    as opposed to this:

    because I don't see other people doing this often, and I was wondering if there is something wrong with declaring variables like that

  • satheesh_k

    Hi I want to create a class where it has two class members, one is array size and another is array itself. I want to ask user to input array size.
    How can i initialise array in class constructor based  on user input?

    but i am getting compilation errors. Please suggest a way to do this.

    • - `numArray` has to be a member of `Stack`.
      - Initialize your variable with brace initializers.
      - Missing printed trailing line feed.
      - Use ++prefix unless you need postfix++.

      Dynamically allocate the array in the constructor. Loop until `sample_stack.arraySize` in `main`, extracting into `sampleStack.numArray[i]` in every cycle.

      • Satheesh K

        Thank you, I have done the following but not sure this is what you have said. But it is working fine. if I am missing some thing please let me know

  • Nguyen


    I have two questions in line 14 and line 17.  Could you please explain?

    • Nguyen


      Please ignore my questions.  I could answer myself.  I modified the same program to make sure I really understand.  
      Here is my updated version.

      Thanks, Have a great day.

  • McDidda

    Consider following snippet of code

    So I think here first initialization of m_value will takes place (am I correct) and then  body of constructor will get executed.
    My question is: can I use m_value in the body of "Something()"constructor?

  • McDidda

    hi Alex,
         I'm learning initializatioh list for class member initialization. I wrote the following code:

    My problem is :
    It gets compiled. I guess it means there is no problem with the code. Now although  m_1 is "const int"  still user could change it's value!!!.

  • Mario Drouga

    Why is this not allowed:

  • Dimitri

    1) If uniform initialization is used, which option is preferable?



    2) Is the libraries writing order important?


    • Dimitri

      1) a

      2) sometimes yes (sorry, I had to google first:))

    • 1) a with an overloaded constructor so you can still construct an @RGBA with 3 arguments.
      2) Unfortunately sometimes yes. As long as a header doesn't want to be included in a specific place, sorting your includes alphabetically can help managing your includes.
      C++20 will add modules, which should be independent of their import order.

  • Winchester

    What is the real difference between direct and uniform initialization, performance-wise?

    Something(): m_value(5){}
    Something(): m_value{5}{}

    BTW, lesson 4.1 been recently updated. So the following statements don't apply any more.

    "In lesson 4.1 -- Introduction to fundamental data types, you learned that you could initialize variables in three ways: copy, direct, and via uniform initialization (C++11 only)."

    • There is no performance difference. Uniform initialization works with lists, prevents narrowing casts, and can default-initialize. Direct initialization can't do these things.

      There used to be a performance difference between copy- and direct/uniform-initialization. If I understood correctly, this is no longer the case.

      • Atas

        Dear nascardriver, what is your opinion on this:
        Is it a good advice to never use uniform initialization unless you're initializing an aggregate?

        • I don't agree. Renouncing the benefits of brace initialization, because you don't want to think about the type you're initializing isn't worth it in my opinion.
          I go by "If the type you're initializing might have a list constructor and you don't want to use it, use direct initialization.". This rule has served me good so far and isn't hard to enforce.

  • Hello, I'm confused as to why the compiler doesn't give me an error when I don't
    use uniform initialization for MainWindow &m_mainWindow;
    But does for MainWindow &m_mainWindow{}; and that I have to make it const.

    • Empty initializers lists create a temporary object which is used to initialize the variable.

      Tries to instantiate a @MainWindow and use it to initialize @m_mainWindow. The temporary is an r-value, so you're not allowed to modify it, but referencing it would mean that you can modify it.
      You can think of it like a reference to a literal.

      By not initializing @m_mainWindow at its declaration, you're forced to initialize it in the constructor.

  • J


    Is it acceptable that my type alias only exists in the scope of the RGBA class or is it considered better practice to make it global via a head file?

    • Alex

      It's always better to put things in a smaller scope if you can, so putting your type alias in the scope of the class is better than in the global scope.

  • Envy

    In the segment: Initializing array members with member initializer lists

    The second code snippet reads the following:

    If I'm not completely mistaken the comment on line 9 doesn't make sense.
    In line 4 m_array is declared as const which means any assignments to that array will produce a compiler error.
    Or am I missing something?

  • Barne

    My solution:

    The alias makes it much more readable imo.
    The only eyesore is the static cast, is there a way of just type deffing or using an alias for that or would I need a function like intCast(m_green) that just returns a static cast?

    • * Line 32: Initialize your variables with brace initializers. You used direct initialization.
      * Line 8, 9, 10, 11: Initialize your variables with brace initializers.

      > intCast(m_green) that just returns a static cast?
      That wouldn't make the situation any better, would it? All it does is remove the template argument.

      Arithmetic on types smaller than int promotes those types to an int. You could use the unary operator+.

      But the cast is easier to understand.

  • Max Morgan

    Error: no matching function for call to 'RGBA::RGBA (int, int int)'

    • * Line 14, 20, 35: Initialize your variables with brace initializers. You used direct initialization.
      * Line 8, 9, 10, 11, 32: Initialize your variables with brace initializers.
      * Line 19, 25: Limit your lines to 80 characters in length for better readability on small displays.

      There is no constructor that accepts 3 ints.

Leave a Comment

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