Search

8.5 — Constructors

Constructors

A constructor is a special kind of class member function that is executed when an object of that class is instantiated. Constructors are typically used to initialize member variables of the class to appropriate default values, or to allow the user to easily initialize those member variables to whatever values are desired.

Unlike normal 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)

A constructor that takes no parameters (or has all optional parameters) is called a default constructor.

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). When we create an instance of the Fraction class, this default constructor will be called immediately after memory is allocated, and our object will be initialized. For example, the following snippet:

produces the output:

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!

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

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

This constructor has been defined in a way that allows it to serve as both a default and a non-default constructor!

Classes without default constructors

What happens if we do not declare a default constructor and then instantiate our class? The answer is that C++ will allocate space for our class instance, but will not initialize the members of the class (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_nMonth, m_nDay, and m_nYear were never initialized. Consequently, they will hold garbage values. Generally speaking, this is why providing a default constructor is almost always a good idea:

8.6 -- Destructors
Index
8.4 -- Access functions and encapsulation

42 comments to 8.5 — Constructors

  • 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;

  • 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;
      }

  • vitalreddy

    HI...This is good tutorial..very nice... i studied the whole constructors but in this lesson i have some doubt about constructors.....please give explanation about object because object can create memory?...why again constructor create memory....how to it create....without constructor we can't create memory.? please give me reply for this one............:)

  • spidey

    Hey!
    I joined in new and think I have the answer to Renu's query(just a few years late, though) which is 3rd from the top.

    Renu, classes are just the blueprint of how you want your object to look like and behave. It does not allocate any memory unless and untill an object fot it is instantiated. The very obvious reason why constructors are called only when an object is created. On the other hand, since static variables ought to get shared amongst multiple object, it has to be defined within the class itself. Otherwise, each instance might try to set a different value for it and 'static' would lose its very meaning :( Moreover, trying to initialize a non-static variable inside a class would be synonymous to trying to install a television in the blueprint architechture of your living room(which is actually lying on the paper) :P

  • ccc

    Hi Alex,

    Thank you so much for such a great tutorial. However, I would like to use this section to indicate what is consistently missing in this tutorial. When discussing class, I think many reader will be more interested in object in the heap than stack.

    ***
    In the above example, because we declared a Date object, but there is no default constructor, m_nMonth, m_nDay, and m_nYear were never initialized. Consequently, they will hold garbage values. Generally speaking, this is why providing a default constructor is almost always a good idea:
    ***

    will be true for stack object but it will not be true for heap object. For example:

    #include

    using namespace std;

    class Date
    {
    private:
    int m_nMonth;
    int m_nDay;
    int m_nYear;
    public:
    int getMonth(){return m_nMonth;}
    int getDay(){return m_nDay;}
    int getYear(){return m_nYear;}
    };

    int main()
    {
    Date cDate;
    // cDate's member variables now contain garbage
    // Who knows what date we'll get?

    cout << cDate.getMonth() << "/" << cDate.getDay() << "/" << cDate.getYear() << endl;
    Date *pDate = new Date();
    cout <getMonth() << "/" <getDay() << "/" <getYear() << endl;

    return 0;
    }

    Output:
    -858993460/-858993460/-858993460
    0/0/0

    I found this tutorial purposely omit this distinction. Is there reason for it. However, no matter what. It is really really the greatest c++ tutorial ever. Thank you so much Alex for your hard work.

  • SWEngineer

    Simple well explained tutorial.

    Thanks.

  • 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

Leave a Reply

You can use these HTML tags

<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code class="" title="" data-url=""> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong> <pre class="" title="" data-url=""> <span class="" title="" data-url="">