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 2.1 -- Fundamental variable definition, initialization, and assignment, you learned that you could initialize variables in three ways: copy, direct, and via uniform initialization (C++11 only).

Using an initialization list is almost identical to doing direct initialization (or uniform initialization in C++11).

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

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

Uniform initialization in C++11

In C++11, instead of direct initialization, uniform initialization can be used:

We strongly encourage you to begin using this new syntax (even if you aren’t using const or reference member variables) as initialization lists are required when doing composition and inheritance (subjects we will be covering shortly).

Rule: Favor uniform initialization over direct initialization if you compiler is C++11 compatible

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, in 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”.


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

1) Write a class named RGBA that contains 4 member variables of type std::uint8_t named m_red, m_green, m_blue, and m_alpha (#include cstdint to access type std::uint8_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 optionally 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 2.4a -- Fixed-width integers and the unsigned controversy.

Hint: If your print() function isn’t working correctly, make sure you’re casting uint8_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

71 comments to 8.5a — Constructor member initializer lists

  • srividya

    Its a just an awesome example

  • vvidhu1988

    hi i have a question. Let say there is class A and Class B

    here when i create an object to Class A say

    Is the constructor of class A is called and initializes ‘value’ to 0 or before calling Class A’s constructor, whether Calss B’s constructor will be called? since we also have object(bmember) of class type B.

    Please explain when class B’s constructor will be called.

    Whether in the above code i need to initialize ‘bMember’ of class type B in the Class A’s constructor?? since bMember is also a member in class A. I don’t think it is a proper implementation. Can anyone explain?

    • Nikhil Singhal


      The Ans is Very Simple……

      B constructor first called, because first declaration part is done then A’s Constructor is called, so here B’s object is created first.
      I think you got the answer
      if have any confusion run the following code in debug mode:

  • MrPlow442

    One question.

    Do i have to use body brackets {}?
    Can’t i just write?
    Something() : m_nValue(0), m_dValue(0.0), m_pnValue(0) ; ?

  • petewguy1234

    Good explanation! Thank you!

  • Abhijeet

    Hi Alex,

    You’ve used

    to initialize the variables. There is also the option of using

    Is there any inherent benefit to using one over the other?

  • Jason

    Hi Alex,

    Greatly enjoying your tutorial and very excited to see it completely updated.  The pages you have recently worked on are truly epic.

    I may have missed it, but why does using an initialization list resolve the issues that require const and reference member fields to be initialized at the time of their declaration?

    Best wishes and thank you!

    • Alex

      > why does using an initialization list resolve the issues that require const and reference member fields to be initialized at the time of their declaration?

      Because the initialization list provides initialization values for the member variables, whereas assigning values to the members in the body of the constructor is considered an assignment (not an initialization, even though the constructor itself is called to initialize the class object). As you’re aware, const variables and references require that they be initialized.

  • chiva

    Hello I am a new one here. I am studying in university now.
    Now let’s me release my questions that I don’t understand.
    I would like to understand well on How to make Array Initialize using with default constructor.
    Please share and explain

    I thank you all in advanced

    • Alex

      Prior to C++11, I don’t think there’s a way to initialize a member array.

      In C++11, you can use uniform initialization:

  • v.kurenkov

    Good Day!
    Your result ain’t right (r=0 g=0 b=0 a=255), there should be r=0 g=127 b=127 a=255

    Thank you, site’s just awesome!

    • Alex

      Yup, thanks for pointing that out. Fixed!

      • J3ANP3T3R

        hey alex just wanted to add that the above lessons seems to be far from the quiz answer. i ended up with

           RGBA () : m_red {0}, m_green {0}, m_blue {0}, m_alpha {0}

        instead of

           RGBA(uint8_t red=0, uint8_t green=0, uint8_t blue=0, uint8_t alpha=255) :
                m_red(red), m_green(green), m_blue(blue), m_alpha(alpha)

        why are those like that ?

        • Alex

          My constructor allows the user to specify values for red, green, blue, and alpha when an RGBA object is constructed. Because the values are all also defaulted, this constructor can be used as a default constructor when no parameters are provided.

          Your constructor initializes everything to 0 and is incapable of taking initial values for red, green, blue, and alpha. How would a user set those values?

          • J3ANP3T3R

            i’m sorry my English is not that good i may have said something that implies differently. i wasn’t saying my answer is better (my answer was coming from a newbie). i’m saying my answer was derived from the instructions of this lesson but when it came about on the quiz i got surprised because the lessons did not mention anything about that type of constructor. so i was wondering if you could elaborate on that answer.

            in the example ;

            i get that this would initialize these 3 variables to 0 0.0 and 0 respectively. but in the answer

            what does those assignments mean ? are they default values ? they look like default values from a function type. how do they differ from the initializers outside ? im just somewhat curious that’s all.

            yep ! there is something im not getting here cause mine was from the examples above. i will start over on this page again until i get it thanks :).

            • Alex

              I see what you mean -- yes, the lesson was a bit deficient in this regard. I’ve updated it slightly, adding an example that is a little closer to what the quiz is asking you to do.

              The assignments in the constructor parameter list are simply defaulted parameters just like any other normal function can have. If the user doesn’t pass in a value for that parameter, the defaulted value will be used.

          • J3ANP3T3R

            oh ok so in uint8_t red=0, uint8_t green=0, uint8_t blue=0, uint8_t alpha=255 are parameters that allow the user to specify each values and the "=0" are the default values for when no parameters are provided ? if so what does :
                    m_red(red), m_green(green), m_blue(blue), m_alpha(alpha) do ?

            thanks 🙂

          • J3ANP3T3R

            please correct me if i’m wrong …

            test instantiate RGBA teal{0,100,0,50}

            - first to be evaluated is uint8_t red=0, uint8_t green=0, uint8_t blue=0, uint8_t alpha=255
            - so red defaults to 0 green is set to 100 blue defaults to 0 and alpha set to 50 by the user.
            - next, values for red green blue alpha is initialized ?
              : m_red(red), m_green(green), m_blue(blue), m_alpha(alpha)

            • Alex

              Since you’ve provided values for all of the parameters, none of the defaults are used. red=0, green=100, blue=0, and alpha=50, and m_red, m_green, m_blue, and m_alpha get initialized to those values respectively.

  • Pisces

    Hello and thank you for these excellent tutorials! This must be the best learning site ever.

    Could you elaborate if default values initialize or assign variables? What will happen in this case?:


    • Jeff

      I’d like to add to this question. In the quiz solution, if I understand correctly, it seems the user can also safely instantiate "teal" with

      since all members have default values, is that correct?

      • Alex

        would call the default constructor, which would assign m_red, m_green, and m_blue the value 0. This would be the color black, not teal.

    • Alex

      Initialize. However, if your constructor has an initializer list that gets executed, those will take precedence.

      So, in your example case, assuming your Something() default constructor is called, your Something object will end up with values 0, 0.0, and 0 respectively.

  • Nicolas

    Dear Alex,

    First of all, thank you so much for your tutorials, they have helped me a lot! The new updates also help a lot. The quizzes are a great learning tool.

    I am using a library called GDAL (I already installed it properly and tested it). Now I am trying to create some classes that use some other classes from GDAL. I first created the LC_Raster and it worked fine. Then I created the LC_Product and I get this error: "error C2512: ‘LC_Raster::LC_Raster’ : no appropriate default constructor available"

    I would appreciate a lot if you could please give me some insight about the mistake I am making, since I have spent hours trying to find it without success.

    I am using Visual Studio 2010, so I think it does not have C++11 and that is why the initialization of std::vector is weird. In a few days I will have my usual computer back and I would be able to use Visual Studio 2015.

    Here is the code:

    #include “stdafx.h”
    #include “gdal_priv.h”
    #include “gdal_alg.h”
    #include “cpl_conv.h”
    #include “cpl_string.h”

    class LC_Raster
    std::string m_parentProductName;
    int m_year;
    std::string m_rasterName;
    GDALDataset* m_SourceRasterDS;

    LC_Raster(std::string parentProductName, int year): m_parentProductName(parentProductName), m_year(year)
    std::stringstream os;
    os <> yearAsString;

    m_rasterName = “Recon_” + m_parentProductName + “_” + yearAsString + “.tif”;

    m_SourceRasterDS = (GDALDataset*) GDALOpen(m_rasterName.c_str(),GA_ReadOnly);

    void setProductName (std::string name)
    m_parentProductName = name;

    void setRasterYear (int year)
    m_year = year;

    std::string getParentProductName () {return m_parentProductName; }
    int getRasterYear () {return m_year; }
    std::string getFileName () {return m_rasterName; }
    GDALDataset* getRasterGDAL () {return m_SourceRasterDS; }

    class LC_Product
    std::string m_productName;
    std::vector m_productYears;
    int m_numberOfRasetrs;
    std::vector m_rastersOfProduct;


    LC_Product(std::string productName, std::vector productYears): m_productName(productName), m_productYears(productYears)
    m_numberOfRasetrs = productYears.size();

    for (int iii=0; iii < productYears.size(); iii++)
    m_rastersOfProduct[iii] = LC_Raster(productName,productYears[iii]);


    std::string getProductName () {return m_productName; }
    std::vector getProductYears () {return m_productYears; }
    int getNumberOfRasters () {return m_numberOfRasetrs; }

    std::vector calculateNeighboringYears (int yearToPredict, int deltaT)
    std::vector neighborYears;
    int numberOfNeighboringYears = neighborYears.size(); //This is the same as 0

    for (int iii=0; iii = (yearToPredict-deltaT)) && (m_productYears[iii] <= (yearToPredict+deltaT)))
    numberOfNeighboringYears += 1;
    neighborYears[numberOfNeighboringYears-1] = m_productYears[iii];

    return neighborYears;

    int _tmain(int argc, _TCHAR* argv[])

    //Array with the name of the products
    std::array productNames = {“BC”,”Hist”,”LF”,”MODIS”,”NLCD”,”NLCD92″};

    //Vectors with the year of eahc product
    std::vector yearsBC;
    for (int yearBC = 1938; yearBC <= 2005; yearBC++)
    std::vector yearsHist (1,1977);
    int arrayYearsLF[] = {2001,2008,2010,2012};
    std::vector yearsLF (arrayYearsLF, arrayYearsLF + sizeof(arrayYearsLF) / sizeof(int) );
    std::vector yearsMODIS;
    for (int yearMODIS = 2001; yearMODIS <= 2012; yearMODIS++)
    int arrayYearsNLCD[] = {2001,2006,2011};
    std::vector yearsNLCD (arrayYearsNLCD, arrayYearsNLCD + sizeof(arrayYearsNLCD) / sizeof(int) );
    std::vector yearsNLCD92 (1,1992);

    LC_Product NLCD(productNames[4], yearsNLCD);

    LC_Raster rasterTrial(“NLCD”,2001);

    std::cout << rasterTrial.getFileName() <GetGeoTransform(GeoTransform);

    for (int iii=0; iii < 6; iii++)
    std::cout << GeoTransform[iii] << "n";

    return 0;

    I apologize, I could not figure how to format the code.

    Thank you so much for your attention and time.

    • Nicolas

      Here is the code in the appropriate format, I apologize again.

      • Nicolas

        I got the code to build and work by creating a default constructor for LC_Raster and a default constructor for LC_Product. However, I don’t understand why that is necessary since I never call the default constructors in main.

    • Alex

      Taking a quick look at this, I’m not sure why you’d be getting an error about not having an appropriate default constructor. As far as I can see, in both places where you’re declaring an object of type LC_Raster, you’re doing so with parameters. What line of code is it complaining about?

      • Nicolas

        Dear Alex,

        Thank you for your help and time. I found the issue. In the constructor of LC_Product I have a std::vector m_rastersOfProduct containing LC_Raster variables. Te vector is resized, and as soon as it is resized, it tries to call the default constructor of LC_raster, which does not exist. Thus, the solution is to not resize the vector and instead, push_back the elements, or to create a default constructor for LC_raster.

  • nick

    #include <iostream>
    #include <cstdint>
    using namespace std;
    class RGBA {
    RGBA (uint8_t red,uint8_t green,uint8_t blue)
    void print() {cout<<"R : "<<(int)m_red<<"\nG : "<<(int)m_green<<"\nB : "<<(int)m_blue<<"\nA : "<<(int)m_alfa;
    int main(){
    RGBA o(0,127,127);
    return 0;

  • cei

    Hi. I am a bit confused: is it better to use member initializer lists or directly assigning a default value to member variables via non-static member initialization?
    Up until now I have always used the former, but now it seems to me more convenient to use the latter, as it makes a class easier to understand (no need to jump to the member initializer list to see what the initial values of the class’ members are).

    • Alex

      Non-static member initialization is preferred, if you have a compiler that supports it, for precisely the reason you’ve identified.

      You can still use member initialization lists for any values the constructor needs to change from the default value.

  • Lokesh

    At the beginning of this lesson, the names of variables used in code and those used to explain the code below it are different.
    "When the class’s constructor is executed, m_nValue, m_dValue, and m_chValue are created." It should be:
    "When the class’s constructor is executed, m_value1, m_value2, and m_value3 are created."

  • Lokesh

    In section "Initializing array members with member initializer lists", you said that prior to C++11, you could only zero the elements using a blank list for initializing the members of an array. Following is the example code provided:

    However, since the array elements are of type <const int>, we cannot assign values to them once we have initialized them(in this case with zero for all elements). So, my question is how did we initialize elements of an integer array of type <const int> prior to C++11 when an instance of a class is created ?

  • Lokesh

    I think you should not use the words "explicit assignment" as there is no such thing as implicit assignment. It is more confusing since we use the terms implicit and explicit when referring to initialization (uniform initialization is also implicit which happens to work for all data types). You should say just "assignment". I am referring to the sentence:
    "Note that we no longer need to do the explicit assignments in the constructor body, …"

  • SJ

    Hi Alex,

    I am a bit confused with the solution to the quiz question. I am not sure what the purpose of instantiating the member variables to 0,0,0,255 was, as in here:

    because we immediately go ahead to include a constructor, requiring the user to include the RGB color values upon instantiating of an RGBA object. So something like

    gives me an error and not the default color object containing 0,0,0,255.

    So I’m just wondering why we defaulted these values when we declared the member variables?

    *** Edit: ***
    I see you touch upon exactly this in the next topic. But I believe the solution here should still be updated?

    • Alex

      I’ve removed the non-static member initializers since we haven’t covered those yet.

      • SJ

        Was I correct in saying that

        would not compile? There was no constructor for it that took no arguments and there was one that required the RGB arguments.

        Also the solution still says to default the values to 0,0,0,255 so I think either the question or the solution should be altered 😛

  • Irene

    How can the constructor have 4 values while

    has only three? My compiler takes that as an error.

    • Alex

      The constructor has default values for all parameters:

      So any parameter that is not provided when an RGBA object is created will use the defaulted value.

      RGBA teal(0, 127, 127) is the equivalent of RGBA teal(0, 127, 127, 255) with the defaulted parameter.

  • Connor

    Alex, when I create an array of the following class, and print each element from the PrintPoint() member function, each "m_key" is off by 1 (with the first m_key printed being garbage- i.e. first element of the array is a garbage value but time entered is accurate):

    However, if I

    "m_key" in the constructor function:

    then the all elements of the array print as expected. Why can’t I static_cast a member variable, within the private specifier, when the class is instantized?

    • Alex

      It has to do with the order that statements are getting evaluated. In the top example, since you aren’t initializing your member values using an initializer list, the first thing that happens is the members get initialized using any default values. m_pointValue gets the value of m_key, which is uninitialized at this point. Then the body of your constructor runs, which initializes m_key and m_timeEntered, but leaves m_pointValue with the garbage value it got initialized with. In the bottom case, you’ve ensured m_key has a valid value before assigning it to m_pointValue.

      I think you might be able to solve this for the top case by initializing your member variables in the constructor using an initializer list instead of assignment (which you should be doing anyway).

  • Hannah

    Hi Alex,

    thank you for sharing these tutorials with us!

    I have a question about the quiz task. Why are we using fixed-width integers for the members if we need to cast them to int later for cout? If the values we assign to our members do not fit into int, we will have a problem as soon as we cast them, won’t we?

    Again, thank you the awesome tutorials!


    • Alex

      It’s only int8_t and uint8_t that have a potential issue, because some compilers implement them as a typedef of signed and unsigned char respectively. And std::cout prints those as chars rather than integers.

      While we could have used type unsigned char instead of uint8_t, since we’re not using these types as chars, it doesn’t seem appropriate.

      And yes, if you overflow your integers, you’ll get undesired results.

      • Hannah

        Ok, we don’t want to print uint_8 variables because cout might produce garbage.
        What confuses me is this:

        I was assuming we use uint_8 for m_alpha because 255 might not fit into int. So far, so good.

        But we are later casting m_alpha to int, and m_alpha is still 255. Why can we be sure that 255 will fit into int now?

        Thank for your time!

        • Nyap

          uint8_t is 1 byte while unsigned ints are 4 bytes. 1 byte can hold 2 to the power of 8 (all numbers up to 256) and an unsigned int can hold 2 to the power of 32 (all numbers up to 4294967296)
          it looks like you need a refresher on chapter 2

        • Alex

          uint8_t won’t print garbage, it will just may print characters as chars instead of integers, which isn’t what we want in this case.

          We are using uint8_t because we want a type that represents exactly 8 bits, and uint8_t (being a fixed-width int) does. An int is guaranteed to be at least 2 bytes. It’s safe to convert a smaller int into a larger one (in this case, a 1 byte int into a 2 byte int).

  • Peter

    Hi Alex,
    You wrote in 2.4a that
    C++ will freely convert between signed and unsigned numbers, but it won’t do any range checking to make sure you don’t overflow your type.

    So i am having problem with validating input values.
    I can only think of doing this

    are there better ways of handling this?

    • Alex

      Yes, you can handle it that way (by taking a signed value with a larger range than the unsigned value you need, and asserting the value passed in is legitimate). This is probably how I’d handle it, at least so long as it was sufficient for what I was doing.

      You could also make the parameters strings, do input validation on them, and convert them into integer values if they pass validation. This is far less efficient, but gives you more control.

  • Peter

    Sorry the first assert conditions are suppose to be >= 0 not > 0

  • Anddo

    It’s nothing but worth mentioning, just noticed this output

    So when I tried the code on Visual Studio the output was

    Again and ever, thank you!

  • Vijay

    Hi Alex, It would be very helpful for us if you provide video tutorial. Thank you very much for this tutorial.

  • Matt

    In your first and second code examples up top, I think you may have unintentionally assigned (int) m_value1 a value of 1.0

  • Matt

    I was wondering why, in Codeblocks, I don’t have to include the header file <cstdint> in order to use uint8_t… nor do I have to use the std namespace.

    • Alex

      Unsure. I guess Code::Blocks is including some version of the fixed-width integers outside of the std namespace.

      My advice would be to not use these, and #include cstdint and use the versions in the std:: namespace. That way, if you ever move your code to another compiler, it will still work.

  • Adam

    I tried the Quiz,

    and I got the desired values but what if I want to initialize m_red or m_alpha in C++ (not C++11 or C++14), without assignment or creating any functions, is there a way to do it.



    • Alex

      The method used for initializing m_red and m_alpha is pre-C++11 compliant.

      The only thing that’s C++11 specific in the quiz solution is the use of type std::uint8_t. If you’re pre-C++11, you can substitute an unsigned char.

Leave a Comment

Put C++ code inside [code][/code] tags to use the syntax highlighter