Search

Language Selector

8.5 — Constructors

When all members of a class (or struct) are public, we can initialize the class (or struct) directly using an initialization list or uniform initialization (in C++11):

However, as soon as we make any member variables private, we’re no longer able to initialize classes in this way. It does make sense: if you can’t directly access a variable (because it’s private), you shouldn’t be able to directly initialize it.

So then how do we initialize a class with private member variables? The answer is through constructors.

Constructors

A constructor is a special kind of class member function that is automatically called when an object of that class is instantiated. Constructors are typically used to initialize member variables of the class to appropriate default or user-provided values, or to do any setup steps necessary for the class to be used (e.g. open a file or database).

Unlike normal member functions, constructors have specific rules for how they must be named:
1) Constructors should always have the same name as the class (with the same capitalization)
2) Constructors have no return type (not even void)

Note that constructors are only used for initialization. They can not be explicitly called.

Default constructors

A constructor that takes no parameters (or has parameters that all have default values) is called a default constructor. The default constructor is called if no user-provided initialization values are provided.

Here is an example of a class that has a default constructor:

This class was designed to hold a fractional value as an integer numerator and denominator. We have defined a default constructor named Fraction (the same as the class).

Because we’re instantiating an object of type Fraction with no arguments, the default constructor will be called immediately after memory is allocated for the object, and our object will be initialized.

This program produces the result:

0/1

Note that our numerator and denominator were initialized with the values we set in our default constructor! This is such a useful feature that almost every class includes a default constructor. Without a default constructor, the numerator and denominator would have garbage values until we explicitly assigned them reasonable values.

Constructors with parameters

While the default constructor is great for ensuring our classes are initialized with reasonable default values, often times we want instances of our class to have specific values. Fortunately, constructors can also be declared with parameters. Here is an example of a constructor that takes two integer parameters that are used to initialize the numerator and denominator:

Note that we now have two constructors: a default constructor that will be called in the default case, and a second constructor that takes two parameters. These two constructors can coexist peacefully in the same class due to function overloading. In fact, you can define as many constructors as you want, so long as each has a unique signature (number and type of parameters).

So how do we use this constructor with parameters? It’s simple:

This particular fraction will be initialized to the fraction 5/3!

In C++11, we can also use uniform initialization:

Note that we have given the second parameter of the constructor with parameters a default value, so the following is also legal:

In this case, our default constructor above is actually somewhat redundant. We could simplify this class as follows:

Although this constructor is still a default constructor, it has now been defined in a way that it can accept user-provided values as well.

Classes without default constructors

If your class has no other constructors, C++ will automatically create an empty default constructor for you. Because the empty default constructor does not initialize any of the class’s member variables, if you use it to allocate an object of your class, the member variables of the class will not be initialized (similar to what happens when you declare an int, double, or other basic data type).

For example:

In the above example, because we declared a Date object, but there is no default constructor, m_month, m_day, and m_year were never initialized. Consequently, they will hold garbage values.

However, if you do have other non-default constructors in your class, but no default constructor, C++ will not create an empty default constructor for you. In this case, the class will not be instantiatiable without parameters. For example:

Prior to C++11, it’s a good idea to always provide at least one constructor in your class. This will prevent C++ from creating an empty default constructor, ensuring that users don’t instantiate objects of your class that have uninitialized members.

C++11: Non-static member initialization

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

Note that constructors may still be used even with non-static member initialization. If a member variable is initialized via non-static member initialization and via a constructor, the constructor will take precedence.

Generally speaking, non-static member initialization should be favored over default constructors with no parameters, as it’s clearer what default values the member variables get initialized with.

Rule: Favor giving member variables default values using non-static member initialization instead of a default constructor with no parameters.
Rule: Provide at least one constructor if all members aren’t initialized using non-static member initialization.

Quiz time

1) Write a class named Ball. Ball should have two private member variables with default values: m_color (“Black”) and m_radius (10.0). Ball should provide one or more constructors to set only m_color, set only m_radius, or set both values. Write a function to print out the color and radius of the ball.

The following sample program should compile:

and produce the result:

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

Show Solution

2) What happens if you don’t declare a default constructor?

Show Solution

8.5a -- Constructor member initializer lists
Index
8.4 -- Access functions and encapsulation

66 comments to 8.5 — Constructors

  • Cody

    As a review you could include protecting m_nDenominator from invalid assumptions by making sure it is not set to 0. This is because, if I remember correctly, dividing anything by zero will probably cause the program to crash so the function GetFraction() would most likely crash the program if the denominator is 0.

  • Abhishek

    what’s assert() ?

  • Renu

    class Fraction
    {
    private:
    int m_nNumerator =10;
    int m_nDenominator=20;

    public:
    Fraction() // default constructor …….

    I tried initialising m_nNumerator =10 and int m_nDenominator=20

    got this error ” only static const can be initialised ….”

    Then I tried

    private:
    static const int m_nValue=22;
    int m_nNumerator ;
    int m_nDenominator;
    It worked.

    Could you please explain? Does that mean private member variable cannot be initialised when they are declared? If so ,is there any specific reason for that?

    Thanks,
    Renu

    • (Edit: This comment is now outdated due to a change in C++11 -- see next comment in this thread)

      In a class, you can’t initialize values on the line they are declared like that. Non-static class values should be initialized in the constructor body or initialization list. Static class values should be initialized in the body of the class definition.

      I am not sure what the reasoning is for this design decision. I presume simply because the constructor is the function that is supposed to initialize your values. If you were allowed to do default values this way, then many variables would be initialized twice (once in the declaration, once in the constructor). This would be both inefficient and confusing.

      • Connor

        Hello Alex,
        when I initialize the class variables after declaring them the program will still compile without error.

        could this just be the way my compiler is set up (I’m using code::blocks) or am I not grasping the concept?

        • Alex

          This is one of my favorite features of C++11. Starting with C++11, it’s now possible to assign struct and class members a default value using standard initialization syntax. This means you don’t have to initialize these values in the constructors.

          If you have a value initialized both on the declaration line AND in the constructor, the constructor will take precedence. e.g:

          m_whatever will be initialized to 9.

  • It’s really help full for students like for me .
    I had recommended this to my fiends too.

  • Do constructors must have same name as class or can have different name?

    thanks.

  • Maryam

    THANKU guys…. i was facing problem in parameterized constructor. thanks a lot again…

  • Vishal

    hello alex,
    When i compiled following program i got an error that-

    Ambiguity between Con::Con(int) & Con::Con(float)
    my query is that Why this is so? We can do same thing with functions(i did it in this program too) then why cant with Constructors???

    • baldo

      The error appears because the compiler treats the number 10.8 as double by default. That is why you get the ambiguity error. Replace 10.8 with 10.8f so the compiler knows that the number is a float number.

  • Paulius

    Hi Alex,
    I have the following class:

    and using this

    initializes posX to 10. Is there a way, i can initialize first constructor parameter to default value, and second one to something else?

    I want to do something like this: (ofc, this example doesn’t compile)

    Thanks,
    Paulius

    • codeez

      No, remember parameters replace from left to right. It wouldn’t hurt to just call it with point(0, 10); though.

    • bruno

      If you always want to call

      Meaning that if just one parameter is given, x will be default and y will be the int.
      Then you could just reverse the order of you parameters

  • Ramakrishna

    hello Alex,
    This is the first time iam seeing this site actually iam
    from non computer background, eventhen iam able to understand easily..
    Really good job
    thanks Alexji………..

  • Mark

    I haven’t programmed for many years as OOP seemed too scary but it’s all coming together really clearly now thanks to this this site. I’m starting to see the elegance of this language. Many thanks Alex for your clear and concise tutorial.

  • Vineet

    hi,
    Your tutorial is nice and gives a clear understanding of constructors.

    Thanks,
    Vineet

  • andi

    Hi Alex,
    Just want to say … it’s really great tutorial. Thanx it helps me a lot. i like the way you make your explaination, it’s simple and easy to understand.
    cheers,
    andi

  • SWEngineer

    Simple well explained tutorial.

    Thanks.

  • gantashalavenki

    can we call constructor manually like any other member functions?….after intializing varialbes using constructor can we call constructor once again to reinitialize?

  • rmusty

    Hi, I tried making a program that utilizes constructors and takes the users name and birthday as an input and outputs his/her age. I am getting the following problem:
    ~~~~~~~~~~
    (56): error C2228: left of ‘.calc’ must have class/struct/union
    (57): error C2228: left of ‘.output’ must have class/struct/union
    ~~~~~~~~~~

    My code:

    #include “stdafx.h”
    #include
    #include
    #include

    using namespace std;

    class Person
    {
    private:
    char c_strName[25];
    int c_month;
    int c_day;
    int c_year;
    int c_age;

    public:
    Person(char *strName = “No Name”, int month = 1, int day = 1, int year = 1900)
    {
    strncpy_s(c_strName, strName, 25);
    c_month = month;
    c_day = day;
    c_year = year;
    }

    void calc()
    {
    time_t now = time(0);
    tm *locTime = localtime(&now);

    int curMonth = 1 + (locTime -> tm_mon);
    int curDay = locTime -> tm_mday;
    int curYear = 1900 + (locTime -> tm_year);

    c_age = curYear - c_year;

    if(((curMonth - c_month) > 0) && ((curDay - c_day) > 0))
    {
    c_age = c_age - 1;
    }
    }

    void output()
    {
    cout << "Your age is: " << c_age << endl;
    }

    };

    int _tmain(int argc, _TCHAR* argv[])
    {
    Person cBob();
    cBob.calc(); // ERROR POINTS TO THIS LINE
    cBob.output(); // ERROR POINTS TO THIS LINE

    return 0;
    }

    • McGlear

      In case somebody has a similar problem:

      When creating an instance of a class, you have to omit the parentheses! You are not calling a function but creating an instance of your Person class.

      int _tmain(int argc, _TCHAR* argv[])
      {
      Person cBob; // This should do the trick
      cBob.calc(); // No error anymore
      cBob.output(); // Compiles fine as well.

      return 0;
      }

  • kekie

    Okay, so default constructors with optional parameters I get, but I don’t really see the point of default constructors with no parameters. Why not just set the member vars where they’re declared?

    So, to clarify, why do this;

    int m_var;
    public:
    Classname()
    {
    m_var = 6;
    }

    When you can do this;
    int m_var = 6;

    • Alex

      You couldn’t do this before C++11.

      Now that you can, I agree that it’s better to favor the non-static member initialization form than a default constructor with no parameters.

  • Shivam Tripathi

    hii alex…after a long tym m back …:)

    m li’l bit confused about constructor’s (ctor) actual definition…in wikipedia it’s written that " ctor is a sub-routine invoked to ‘create an object’ "…but u mentioned (and also i hv heard from  a lot of person saying) that ‘ctors’ come in existence when ‘object is created’…

    so what’s actually true…do ctor’s come in existence when object is created….or ‘object’ come in existence when ‘ctor’ is called…

  • Alex, why we can’t initialize a member variable when declaring it. Code::Blocks has no problem with this program:

    And the output is:
    10
    20
    0.5

    I heard that we can’t initialize member variables like this(but code::blocks does not throw any error). Is that true? If not, then why use constructors?

    • Alex

      As of C++11, you can now set default values directly on member variables of structs and classes. Prior to C++11 (when this tutorial was written), you couldn’t do that. I’ll definitely mention that when I rewrite the lesson!

  • vish

    i am not understanding here. i can initialize numerator and denominator in my main fuction why i use constructor?
    or the thing is that constructor used for default initialization but if i do not want a default initialization why would i use constructor?

    • Alex

      If numerator and denominator are private members of the class, how do you intend to initialize them from your main function? I suppose you could use public functions (e.g. setNumerator()) to do so, but this is clunky. I think you’ll agree that:

      is easier than:

      The entire purpose of constructors is to initialize a newly created object. You can provide multiple flavors of constructors to handle different types of initialization: one for default initialization, one or more for initialization where the user provides input values, and others for other types of initializations (e.g. conversions from other types, etc…)

  • vish

    Thanx Alex. Now i found constructor a very useful and powerful member of a class. i read this chapter twice and i got it. Sometimes constructor itself looks like function. i think i ll get use to with more practice.

  • vish

    oh yes constructor is a class memeber function got it.

  • Mr D

    Ok, so in your last example of the chapter, you create a class that has a default constructor value, but also accepts an argument to user-define the value of the constructor? And the user-defined one takes precedence? Hence:

    • Alex

      There is only one constructor here, and it is the default constructor. It just so happens that this default constructor takes an optional parameter that can be used to specify the month.

      In the first case, you’re calling the default constructor and using the default value for parameter nMonth.
      In the second case, you’re also calling the default constructor but with a supplied value for parameter nMonth.

  • Gopal

    A question not related to Constructor: Why uninitialized variable always contains garbage valve? Why is not just simply 0 or 0000 0000?

    • Alex

      C++ doesn’t initialize variables by default because there’s a performance cost to doing so. If you want an initialized variable, do it yourself. :)

      It’s worth noting that many uninitialized variables will contain the value 0, when the memory allocated for the variable happens to be set to 0. In this case, the 0 is a garbage value. Running the program again may produce a different result.

  • Gopal

    Hi Alex,

    Can we define more then one Constructor (and Destructor) within a Class? Note: not by function overloading but all together different Constructors with different names.

  • Aleksandar

    I would just like to say thanks for creating this amazing web site. It helped me a lot while learning C++. My professors are really bad at explaining things and I can hardly understand anything that they are saying. They also give very few examples and there is just a lot of theory. Now, after studying by reading these tutorials, I really think I have a chance to pass this exam. Thank you once again. 😀
    I wish you were teaching at my university. 😀

  • Anthony

    Hey, great tuts. They’ve helped a lot while I get through school. I just wanted to clarify something. Say I have the following constructor:

    and in my main I have this:

    Now, this sets the first name as Test. Say I only know the last name or the payrate. Do I need to make two different constructors only specifying payrate or lastName? Just want to make sure I’m not wasting time typing out all these constructors that aren’t needed. Thanks in advance.

    • Alex

      Yes, if you only know last name or payrate, you’d need to make separate constructors for those. You’d also need to have some way to distinguish first name from last name -- since both are strings, the compiler probably wouldn’t be able to infer which you’d intended.

  • Sophie

    Can you maybe explain why in quiz question 1 the variable color is passed by (const) reference in the constructor (i.e. const std::string &color)? Why is this preferred over passing the variable by value?

    • Alex

      Passing an argument by value would cause the compiler to copy the argument’s value into the parameter. For fundamental types (int, bool, double, enums, and data-only structs) this is fine, because doing so is trivial and fast. For other types (especially classes, such as std::string), making a copy can be expensive. In these cases, it’s better to pass by const reference, to avoid making a copy.

      In short, pass fundamental types by value (or reference, if you need the function to modify the argument), pass classes by const reference.

  • Josh

    "If there are no other constructors in the class, the created default constructor will be public. Otherwise, it will be private (disallowing creation of the object via the default constructor)."

    As far as I known, if user provides non default constructor(s), the default constructor will not be created. Hence, it should not be private, perhaps, I misunderstand it. Could you please help clarify it, thanks a lot.

    • Alex

      You’re correct, my mistake. However, the practical effect is the same: the class can’t be instantiated without parameters. I’ve updated the lesson to be accurate in this regard.

  • In «Constructors with parameters» part, an #include should not end with a semicolon:

  • Matt

    Hello Alex -

    Why do you use the following in the constructor for the Ball class:

    Is there a reason for using a reference variable for the string "color"? Thank you.

    • Alex

      Yes, without the reference, C++ would make a copy of the argument passed into parameter color every time the Ball constructor was called. Since color is a class, this is likely to be slow, and unnecessary.

      Passing in a const reference allows us to avoid making a copy of the argument passed into color and just use the argument itself.

  • Aditya

    Why does the constructor have to be public? We haven’t called it right? Does being private mean that even the compiler can’t access it?

    • Aditya

      So it dawned on me that we are calling the constructor when we define the object. Please correct me if i’m wrong.

    • Alex

      If a constructor is public, then it can be used by instantiated objects. If the constructor is private, then instantiated objects can not use it (but in C++11 it can still be called by other constructors).

      For example, making a default constructor private means that you can’t instantiate objects like this:

  • Vaibhav

    Hi alex,
    The first example for default constructor that you gave- while calling Fraction default in the int main my compiler is showing error ,whereas instead of using the word default if i use anything else it works..What is happening wrong!?
    The compiler shows error as improper use of typedef ‘Fraction’

    • Alex

      default is a keyword in C++11, so your compiler is probably getting confused. I’ve updated the example to give the variable a different name.

  • Kiran C K

    Hi Alex,

    I was writing a code that just instantiates an object with default constructor and the member function does the other works. here is my code:

    Here are my questions:
    1. I have declared a default constructor under

    . But if it is not defined, it shows error as

    when creating an object. I am wondering that if the class members are private, would the default constructors would also be private. If that is the case, what would be the access if a class has both private and public members?

    2. Without defining the above public default constructor, if I created an object as

    , it shows the error

    .
    And I get the similar error for all the three member functions.

    and

    are doing the same thing. Then why is the compiler shows two different error messages?

    I am using Code::Blocks IDE GCC compiler

    • Alex

      1) If you don’t provide _any_ constructors, C++ will provide a public default constructor for you. In this case, since you have a private non-default constructor, if you remove the public default constructor, C++ won’t provide one for you. This means your class has no default constructors, which means it can’t be instantiated directly.

      2) I think the compiler may be getting confused and thinking that pass is a function, and that Booking pass() is a forward declaration rather than a variable definition.

Leave a Comment

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

  

  

  

15 − 5 =