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 sufficient 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

268 comments to 8.5a — Constructor member initializer lists

  • Tyson


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

    Can someone explain this point, please?

  • codebanger

    How can I pass constructor args to a class that is in an array of structs?

    • Please provide a minimal compilable example of what you're trying to do.

    • codebanger

      Here is a compilable version:

  • Jon

    Hello, I am able to compile (without any warnings, using XCode) and run the program fine while leaving out the "#include <cstdint>" directive.

    Happen to know why that might be?

    • Hi Jon!

      @<iostream> includes @<cstdint>. Since all includes of an included header are copied to your file, you have access to the contents of @<cstdint>.
      Don't rely on transitive includes. @<iostream> is not guaranteed to include @<cstdint>.

  • Yiu Chung WONG

    Under what circumstance do one need a constant class member? Wouldn't private membership and no function referring to that member be enough?

    • Alex

      In the same kind of circumstances you'd want a const non-class object.

      A const member can't be changed even by other members of the class. Private membership would only keep the public from changing the value (other members could still change it)

  • Gaurav Arya

    Almost same like everyone, but with an extra typedef, hope that it does not matter.

    • Hi Gaurav!

      Depending on the version of g++, you can use up to -std=c++2a, allowing you to use more features and preventing you from using obsolete code.
      Your code is not standard c++, because of the extra semicolon after @main. See lessons 0.9-0.11 to properly configure your compiler. For g++, you can use

      * "using" is easier to understand than typedef

      * Line 12-15 can be initialized in-line, allowing you do remove the default values in line 17.
      * Initialize your variables with uniform initialization

      • Gaurav Arya


        Thanks for your valuable inputs. Much appreciated.

        The semicolon after main was accidental. Normally I do not put it after main. This time somehow I missed it.

        Could you please help me understand apart from the extra semicolon, was there anything else which could or did make my program non-standard c++?

        I was a bit puzzled how a semicolon could have such an impact. Normally compilers are designed to ignore the semicolons at such places.

        Unfortunately as it seems my CentOS 7.5 gcc 4.8.5 doesn't support anything above c++11 as I tried a few options. I also tried clang++ but same result. Can't compile anything above c++11.

        I made the changes and this is how it looks now:

        • > was there anything else which could or did make my program non-standard c++?

          > I was a bit puzzled how a semicolon could have such an impact. Normally compilers are designed to ignore the semicolons at such places.
          No. Compilers are designed to follow the standard without exception. Every compiler should abort compilation at the same spot as any other, and they should all produce a semantically equivalent program. Any non-standard behavior is either a bug or a compiler extension. Compiler extensions should be disabled, bugs reported.

          > I made the changes
          You followed my first suggestion, not the other two. Here's what I meant

          • Gaurav Arya

            I understand. Now converted from direct initialization to uniform initialization, curvy to curly braces. Will try harder to get used to uniform initialization. Yes, I learnt C before C++. Thanks again.

  • Gerald

    Hi Alex,

    Is there any reason why you would not initialize the private variables before the constructor?

    #include <string>
    #include <iostream>
    #include <cstdint>

    class RGBA
        std::uint8_t m_red = 0;
        std::uint8_t m_green = 0;
        std::uint8_t m_blue = 0;
        std::uint8_t and m_alpha = 255;

        RGBA(std::uint8_t red, std::uint8_t green, std::uint8_t blue) :
            m_red(red), m_green(green), m_blue(blue)

        void print()
            std::cout << "r=" << static_cast<int>(m_red) << " g=" << static_cast<int>(m_green) << " b=" << static_cast<int>(m_blue) << " a=" << static_cast<int>(m_alpha);

    int main()
        RGBA teal(0, 127, 127);

        return 0;

    • Alex

      No reason that I can think of. I think this example was written before that functionality was added into the language.

      • > I think this example was written before that functionality was added into the language.
        Nice try, but class members could always (1998+) be initialized at their declaration ;-)
        Source: ISO 14882:1998 Section 9.2

        I think this lesson should use the @std::int_fast*_t or @std::int_least*_t types.

        • Alex

          > Nice try, but class members could always (1998+) be initialized at their declaration

          Just to be clear, we're talking about this line:

          std::uint8_t m_red = 0;

          And everything I see indicates otherwise.

          Section 9.2 only has two forms that use an equals sign.

          pure-specifier: = 0
          constant-initializer: = constant-expression

          The latter has a note indicating it only works for static integers or enumerators.

 indicates the this functionality was added in C++11.

          Also, when compiled in g++ with c98 mode, it flags this as requiring -std=c++11, indicating that these were added in C++11.

          Am I missing something?

          I do agree that it's better to use the fast or least types here. I'll update the example.

          • I stand corrected.
            I was referring to
            member-declaration -> decl-specifier-seq member-declarator-list -> member-declarator -> identifier: constant expression
            I read the colon in "identifier: constant expression" as an equals sign. Sorry for making you go through the effort of researching this, but at the same time thanks for doing so!

  • Sid

    I still don't understand why Member Initializer Lists are more preferred. Is it because references can be assigned values in them? Or are they more efficient and faster? Thanks!

  • Kio

    @Alex, missing semicolon:

  • and so:

    the std::uint8_t mand the static casts made the lines long so I split them.  Don't suppose it is 100% necessary but makes for easier to read code.

    • Good old uniform initialization in line 17 and 29.
      See Alex' solution for an easier-to-read way of splitting the lines. Try to avoid lines longer than 80 characters to make your code easier to read on small screens (Also no comments after 80 characters).

  • Dear sir,

    Let's say if I don't initialize with default values, like -

    but I assign the values using -

    visual studio gives me the following error: 'RGBA::RGBA': no overloaded function takes 3 arguments
    1>Done building project "memberVariables.vcxproj" -- FAILED

    Why does it give me an error, even when I assign the values during object creation?

  • Caio Gomes

    Hello, Alex!

    One question. Why is it illegal to do this:

    in the code below?

  • Peter Baum

    Regarding the non-word "performant" see

  • mia

    Hi ALex,

    Thanks a lot for your tutorials. I want to say that i tried piece of code bellow (visual studio 2013), but I got problem.
    it is "Error 1 error C2536: 'Something::Something::m_array' : cannot specify explicit initializer for arrays    

    Would you please why it's happen? Thanks,

    class Something
        const int m_array[5];

        Something(): m_array { 1, 2, 3, 4, 5 } // use uniform initialization to initialize our member array


    • nascardriver

      Hi mia!

      This seems to be a problem with Visual Studio 2013, I suggest you getting a newer version.
      There are some workarounds for this problem over at stackoverflow:

  • aedt

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

    What if this ordering is altered by the compiler to reduce padding?

  • Matt

    Is there any reason to (or not to) initialize the variables at the place of their declaration?


    Edit: turns out this is answered in the very next lesson, doh. Nevermind!

  • C

    There's a grammar mistake in

    fix 'you' to 'your'

  • Travis Touchdown

    Just curious, I got almost everything correct except for the part where printing requires "static_cast<int>(color)".

    May I ask what is static_cast<int>?

    • nascardriver

      Hi Travis!

      static_cast converts a value of type A to a value of type B.

      Casting is covered in lesson 4.4a (Explicit type conversion (casting)). I suggest you to also read Alex' comment in the same lesson about reinterpret_cast and dynamic_cast

  • winsurfwon

    #include <iostream>
    //#include <cstdint>

    using namespace std;

    class RGBA {
        uint8_t m_R;
        uint8_t m_G;
        uint8_t m_B;
        uint8_t m_A;

        RGBA( uint8_t R={0}, uint8_t G={}, uint8_t B={}, uint8_t A={255} )
            : m_R(R), m_G(G), m_B(B), m_A(A) {}

        void print(){
            cout << " R: " << static_cast<int>(m_R)
                 << " G: " << static_cast<int>(m_G)
                 << " B: " << static_cast<int>(m_B)
                 << " A: " << static_cast<int>(m_A) << endl;

    int main() {
        RGBA foo(2, 3);
        return 0;

    Hello, World!
    R: 2 G: 3 B: 0 A: 255
    R: 2 G: 3 B: 0 A: 255

    Process finished with exit code 0
    RGBA( uint8_t R={0}, uint8_t G={}, uint8_t B={}, uint8_t A={255} )

    note the ={} is needed
    I thought Green==2 and Blue==4  <compiler issue maybe>

    C:Program Filesmingw-w64x86_64-7.2.0-win32-seh-rt_v5-rev1mingw64

    same on the C:cygwin64 v2.10.0

  • Jasleen Kaur

    #include <iostream>
    using namespace std;

    class abc{
    const int a=8;



    By writing this code we are changing the constant variable. it means we can re-initialize the constant member using initializer list.

    • Alex

      > By writing this code we are changing the constant variable.

      No, you aren't. The default value of 8 is only used to initialize member 'a' in cases where no explicit initializer for 'a' is provided by the constructor. If an explicit initializer is provided (which your default constructor does), that initialization value is used instead (not also).

      Therefore, member 'a' will initialized once, and the value will not be overwritten. No re-initialization takes place, and no violation of const occurs.

  • I use your code in to test the difference between the non-object-oriented with c++ 11 constructor member initializer list.

    C++ 11 style is about 50 times faster than the non-object oriented style.

    [xx OFtutorial0_helloWorld]$ whatAboutThisGuy
    Time elapsed: 7.506e-06
    Time elapsed: 1.47e-07
    [xx OFtutorial0_helloWorld]$ whatAboutThisGuy
    Time elapsed: 8.664e-06
    Time elapsed: 1.9e-07
    [xx OFtutorial0_helloWorld]$ whatAboutThisGuy
    Time elapsed: 7.646e-06
    Time elapsed: 1.89e-07

    Just play with it.

  • Matias

    Hey Alex, any feedback I can get on this? (I tried using an std::array for the RGBA quiz, also I prefix any classes with the letter C so my code will have CRGBA instead of RGBA). Thanks for the great tutorials, finally I made it to the best bits :glasses:

    • Alex

      Looks good.

      A few minor suggestions:
      1) I don't think it's necessary to cause ColorComponent::MAX_COLORS to a uint8_t -- enums are already treated as integers.
      2) If ColorComponent is only going to be used inside the CRGBA class, it would be better to define ColorComponent inside the CRGBA class (without the ColorComponent namespace). That way it's clear the two are linked, and you won't have to use the ColorComponent prefix inside the class.


    Initializing const member variables at run-time or with users’ input. I never thought this would work because in the previous lessons const/reference member variables have to be initialized, but the below code bypassed it.

    • Alex

      Const just means the variables needs to be initialized with a value, and past that point the value can't be changed. Your program doesn't violate that at all. The following simpler program works too:

  • Benjamin Reynolds

    Hi Alex, I think you should mention how to write the Member Initializer Lists outside the class definition. I know that it may not be the ideal thing to do but it is an option that we can use.

    For Example:



    • Alex

      I don't cover member functions outside the class definition until lesson 8.9. I've updated that lesson to show an example of a member initialization list outside the class definition.

  • Hieu

    Hi, Alex. You have awesome tutorials. I'm wondering why the member variables of RGBA class have to be cast to int in the print() function. Why, if I don't cast them, the program won't output the values?

    • Benjamin Reynolds

      Hey Hieu. m_red, m_green, m_blue, and m_alpha are of the "std::uint8_t" type.

      He is casting them to int because "std::cout" may treat "std::uint8_t" as a "char" type. Which would print a character to the screen instead.

    • Alex

      uint8_t is mostly like a typecast for an unsigned char, so printing the value will print the character whose ASCII code is that value. Not what we're looking for here. Casting to an int ensures we print the numeric value.

  • Shamlei

    Hey it just keeps getting more and more interesting and powerfull and you seem to be able to keep the same high quality of explanations.

    With all of this learned on constructors does that mean a class should only ever have one constructor ?

    Default values and initializer lists seem to make it possible for most cases.


  • Hardik

    Hi Alex,
    In The Given Code :-

    How Can We Instantiate an object of Class A on Line-12 if the default constructor isn't provided in Class A?
    Reply Please :)

    • Alex

      We don't ever create an object of type A without a parameter, so a default constructor isn't needed.

      B b(5) instantiates an object of type B, which allocates memory for B, including the member m_a of type A. B's constructor is then executed with parameter 5, and the variable m_a is initialized using the A(int) constructor to the value of 4.

      Remember, classes are just type definitions. They do not actually allocate memory until an object of the class is instantiated.

      • Hardik

        I think you got me wrong !
        Let Me Start Again.
        We know that compilation starts from the start of the program.Yes? Ok, So When It Encounters Class A it doesnt allocate any memory for it as we know that it is just a type definition. Then It Goes to Class B and there it encounters A m_a but then, Shouldn't it flag it as an error as there is no default constructor provided in Class A?

        • Alex

          No, because a default constructor for A is never called. We only ever initialize A with an integer parameter, so we only need a constructor that can handle an int.

          • Hardik

            It is called on LINE 12, No?

            • Alex

              No. Line 12 just tells the compiler that B contains an A member named m_a. Initialization is handled via the constructors.

            • Hardik

              So, Why does this print "A"?
              Shouldn't it just "tell" the compiler that B contains A member name m_a?

              • Alex

                If you don't explicitly tell the compiler how to initialize a member that is itself a class, the compiler will default to using the default constructor.

                In this case, the B constructor doesn't initialize m_a, so the compiler uses the default constructor for A to initialize m_a.

                • Hardik

                  Just Like That, In The 1st Case We Haven't told the compiler how to initialize member m_a till Line 14. So Why it doesn't flag that line 12 as an error?

                  • Alex

                    Because it's just part of the type definition, it doesn't actually instantiate anything, so there's no need to specify how the variable is initialized at that point.

  • Curiosity

    Look, we all know that a variable can only be created once.Yes?
    So, In The Section : "Member Initialization Lists", How can we create a single member variable twice;
    1st, When we create it.
    Example :-

    2nd, When we initialize it using member initialization lists(initialization involves CREATION too !)
    Example :-

    I hope you have understood my question :)

    • Alex

      Three things:

      1) This is a variable definition:

      2) This is a variable initialization:

      3) This is the variable instantiation:

      When we instantiate variable s (of type Something), the member m_value is created. It is then initialized by the constructor.

      • Curiosity

        That's what i'm asking bro !
        When Vairiable m_value is created for the 1st time, How Can it be initialized (which involves creation too !) ?
        The following isn't valid, No?

        • Alex

          No, that's not valid, as it's a redefinition of x.

          When you type "int x = 5", variable x is first given a memory location, and then it is initialized to 5.

          With classes, when you instantiate an object, the object is first given a memory location, and then the constructor is called to initialize the object.

          With fundamental variables, the definition and initialization are done in the same line. With classes, the definition and initialization are defined on separate lines. This was done so that different constructors can initialize members in different ways, depending on which constructor was called.

          • Curiosity

            So, It Means Re-Creation is allowed in the case of classes !

            • Alex

              I don't know what "re-creation" means in this case. As I said, the difference is that in classes, the definition and initialization happen in separate places. The compiler handles the details. There's no redefinitions here.

              • Curiosity

                It means things "like" these is allowed in the case of classes :-

                note:- I have said "LIKE".

                • Alex

                  I get what you're thinking here, but I think that's a bit misleading. In the int case, the top line actually instantiates an integer. In the class case, defining an int member doesn't actually instantiate an int.

                • Curiosity

                  See, but when we declare an object of this class, A specific amt. Of memory is instanitiated for that object. And Now, Memory is allocated for members also !
                  Now My question arrives, How is member m_x is defined 2 times(1st - Definition(Eg - int x;) & 2nd initialization(involves definition too(Eg - int x = 5;) or is definition and initialization done in different places in classes?

                • Hardik

                  Can you tell me the reason why it is so different in classes?

                  • Alex

                    So that different constructors can initialize the members in different ways if desired. If you had to initialize the variables right where they were defined, then constructors wouldn't be near as useful.

  • Chris

    Due to the wording in your quiz, I interpreted the question in a different way than your solution provided.  The first part was simple enough, if RGBA were instantiated with no arguments, then RGBA members will be initialized to 0,0,0,255

    The second part says if the user passes red, green, blue and optionally alpha, then initialize the members accordingly.  Due to the fact that 'optionally' is used on only alpha, that tells me that all three color components must be provided.  Your solution would allow only red or only red and blue components to be provided.

    My solution according to my own interpretation of the question uses these two constructors.

    Also want to thank you for taking the time to provide these tutorials.

  • Felipe

    Isn't this code format better, for the last question of the quiz?

  • George

    Hi Alex! Very nice site, thank you so much!

    I would appreciate it if you would help me to solve this.

    If we have the following class:

    And the following main function:

    Is this correct:
    1) the constructor for the object y is called (***)
    2) the constructor for the object _y is called (///)
    3) the assignment operator is called (###)

    Thanks in advance!

    • Alex

      (***) and (###) are correct. The constructor for _y is actually called here:

      After the function parameters are assigned, but before the body of the constructor executes.

      This makes sense since the definition of Yyy _y is just a definition, it's not executable code.

Leave a Comment

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