8.5b — Non-static member initialization

When writing a class that has multiple constructors (which is most of them), having to specify default values for all members in each constructor results in redundant code. If you update the default value for a member, you need to touch each constructor.

Starting with C++11, it’s possible to give non-static class member variables a default initialization value directly:

This program produces the result:

length: 1.0, width: 1.0

Non-static member initialization (also called in-class member initializers) provides default values for your member variables that your constructors will use if the constructors do not provide initialization values for the members themselves (via the member initialization list).

However, note that constructors still determine what kind of objects may be created. Consider the following case:

Even though we’ve provided default values for all members, no default constructor has been provided, so we are unable to create Rectangle objects with no parameters.

If a default initialization value is provided and the constructor initializes the member via the member initializer list, the member initializer list will take precedence. The following example shows this:

This prints:

length: 2.0, width: 3.0

Note that initializing members using non-static member initialization requires using either an equals sign, or a brace (uniform) initializer -- the direct initialization form doesn’t work here.

Rule: Favor use of non-static member initialization to give default values for your member variables.

Quiz time

1) Update the following program to use non-static member initialization and member initializer lists.

This program should produce the result:

color: black, radius: 10
color: blue, radius: 10
color: black, radius: 20
color: blue, radius: 20

Show Solution

2) Why do we need to declare an empty default constructor in the program above, since all members are initialized via non-static member initialization?

Show Solution

8.6 -- Overlapping and delegating constructors
8.5a -- Constructor member initializer lists

29 comments to 8.5b — Non-static member initialization

  • Lokesh

    I think the following program demonstrates all the rules about default constructors. I found the concept a bit twisty. I think you should use this particular example for quiz question no.1 as it serves as a summary(it just adds one or two concepts to what already exists in the question).

    • Alex

      I’ve updated the quiz question with some of your suggestions. Thanks!

      • Lokesh

        I kindly disagree with:

        I think we need a default constructor(we have to define our own) because although the private member variables have default values, these are non-static. So, we cannot instantiate an object without any values(no parameters) that will automatically take on the default values provided for the member variables. So, although we have used non-static member initialization, we need to define an "empty" constructor in order for us to instantiate an object with no parameters. As I have said earlier, we need a default constructor as so:

        Secondly, you cannot use "default" as an identifier(in quiz-1 solution) because it is a keyword in C++.

        • Alex

          Agreed with your assessment. Not sure how I messed that up. The article has been fixed.

          • Keanu

            Hi Alex. I was reading the above comment thread and think I may be misunderstanding something. Lokesh says "we cannot instantiate an object without any values(no parameters) that will automatically take on the default values provided for the member variables" when using non-static member initialization without a user-defined default constructor. I was confused by why this would be so when I saw you agree with the comment, I decided to run the provided code without a user-defined default constructor using a print function called by main().
            This is the code:

            This prints: colour:black radius:10
            I compiled the code in visual studio 2015 and an online compiler with the "stdafx" removed - both worked fine and produced the expected outcome. I feel like there’s some sort of blind spot here for me, have I misunderstood Lokesh’s comment?

            • Alex

              Two things to remember:
              1) Constructors determine what type of objects you can create
              2) C++ will create a default public constructor for you if you’ve provided no constructors.

              The reason your code works is because of the latter -- you don’t have any constructors, so C++ is creating one for you, and using it to create ball.

              If you had another (non-default) constructor, this wouldn’t work, even though you’ve defaulted your values. By explicitly defining an empty default constructor, we’re ensuring we can create objects of type Ball with no parameters regardless of whether other constructors exist or not.

            • Keanu

              Ah, I see what happened. For some reason I thought the bit of code which Lokesh says he "kindly disagrees with" was in isolation; I didn’t realize that it was part of a larger segment of code that included non-default constructors. Makes total sense now. Thanks for the speedy response Alex, given you’ve been running this site for around 9 years, it’s extraordinary you still maintain it so well and respond to questions within days.

  • Bassam

    Hi! Alex. Thank you for this very useful explanation. I think you should use double instead of int in the constructor parameters for the second and third example.

  • Joshua Richards

    Would this solution be better since it produces the same output, has only two constructors that can handle all for Ball objects, and demonstrates all of the concepts we have learned in this lesson?

    #include <iostream>
    #include <string>

    class Ball
        std::string m_color{"Black"};
        double m_radius{10.00};

        Ball(const std::string &color="Black", double radius=10.0)
        : m_color{color}, m_radius{radius}
        Ball(double radius)
        : m_radius{radius}
        void print()
            std::cout << "Color: " << m_color
            << ", Radius: " << m_radius << ‘\n’;

    int main()
        Ball def;
        Ball blue("Blue");
        Ball twenty(20.00);
        Ball blueTwenty("Blue", 20.00);
        return 0;

  • P

    Hi, thank you for the tutorial!
    Is it customary to indent the default constructor?

  • Shiva


    Please correct: "…if the constructors do not provide an initialisation values…"


  • Nyap

    What do you mean by non-static

  • Darren

    This is somewhat pedantic but in the example code segments above, the non-static member initialisation is done by assignment initialisation. However, as this is a C++11 thing shouldn’t it be done by uniform initialisation, as per the recommendation in the previous chapter?

  • Ben

    For our Square class, don’t we only need one input parameter because the definition of a square tells us that all sides have the same length? And therefore it should also be impossible to set our Square’s width and length to different values when we construct it. For example:

    Here’s a possible fix?

    That our you can just change the class name to Rectangle.

    Great stuff so far on the C++ tutorial! I am really enjoying it and I feel like I’ve learned a ton.

  • Yan

    Hi, Alex. Thanks for the awesome tutorials.
    I have a strange situation. I did the task in the quiz just like in your solution but my Visual Studio (2013 update 4) doesn’t run it. It throws "Error C2797: List initialization inside member initializer list or non-static data member initializer is not implemented."
    It complains about this line:

    What can be done to fix this? Thanks.

    • Alex

      So it looks like Visual Studio 2013 doesn’t support the brace initialization form for non-static member initialization. You can either switch to Visual Studio 2015, or change your initializers to use an equals sign instead (which seems a bit easier, doesn’t it?). I’ve updated the quiz to use equals signs for now.

  • Sivasankar

    Hi Alex, Thanks for your lessons.
    Just to confirm, the below statement
    "Note that initializing members using non-static member initialization requires using either an equals sign, or a brace (uniform) initializer -- the direct initialization form doesn’t work here" means the way of initializing m_breadth in following code is wrong. Am I correct?

Leave a Comment

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