Constructors in C++

Funny term isn't it? Constructor. But it means just that. The function which constructs an object.
But if you want to be precise, it is function which can bring the object to a known state.

Why do we need a constructor?

Let us understand it with an example. We will write a class A with an integer number n in it.

class A
{
   int n ;
   public:
      void print();
};

void A::print()
{
     cout<<"n of the object is "<<n<<endl;
}

Ok. Now in main function (which as you know is where execution begins.) let us create two objects.


int main()
{
    A obj1;
    A obj2;
    obj1.print();
    obj2.print();
}


When we run this program, this is the output we get.

 
n of the object is 4215766

n of the object is 2359160

Why is it so? n in both obj1 and obj2 is some garbage value, it is not zero. The reason is C++ inherits this property from C that local variable store garbage value. Now we can not have state of the objects uninitialized.

So we create an init() function in the class which initializes the value of n to known value.


class A
{
   int n ;
   public:
      void print();
      void init(int a=0);
};
void A::print()
{
    cout<<n;
}
void A::init(int a)
{
     n = a;
}
int main()
{ 
      A obj1; A obj2;
      obj1.init(4);
      obj2.init();
}


OK, now the class is better. n of obj1 is initialized to 4 and n of obj2 to 0. But again what happens if the user, forgets to call the init function? What happens if he calls it more than once? Again the program gives wrong output.
What we need is a function which is compulsorily called when an object is created. That exactly is a constructor.

A constructor is a special member function gets called implicitly always when an object is created.

It is implicitly called. User program should not and can not call the constructor explicitly.

Let us write a constructor for our class A now.

class A
{
     int n ;
   public:
      void print();
      A(int m);//this is the constructor
};
A::A(int m)
{    cout<<"constructor is called for m="<<m<<"\n";
     n = m;
}
int main()
{
    A obj1(33),obj2(44);
    A obj3(-3);
}

Please observe how the values are passed to the constructor in the main function.

Now our output looks like

constructor is called for m=33
constructor is called for m=44
constructor is called for m=-3
 


Very good. The function is always called and it initializes the object.

But all classes are not this simple. What if the class has more than one data and needs different ways of initializing an object? In that case, we can have overloaded constructors, one constructor with single parameter, one with two parameters etc. and may be one with zero parameters.  

The constructor of a class with 0 parameters is called default constructor because it gets called when you create an object without any parenthesis and any value.  

But in the first program, we did not have any constructor. So what happened to the concept of constructor being called always?  The answer is, in such cases compiler provides a default constructor for the class which does nothing.

 If a class has no constructors compiler provides a default constructor which does nothing

But if we try creating the object with no values now, it does not work but throws a compiler error.


int main()
{
     A obj1(33),obj2(44);
     A obj3(-3);
     A obj4;//This line gives the error
}

The error message may look some thing like this
 g++ constructor.cpp
constructor.cpp: In function 'int main()':
constructor.cpp:38: error: no matching function for call to 'A::A()'
constructor.cpp:25: note: candidates are: A::A(int)
constructor.cpp:5: note:                 A::A(const A&)


So we are not provided with a default constructor for our class because, the class already has one constructor. But this constructor takes one value. So it is not matching to our statement of A obj4. Hence the error. 

We overcome our error by providing default constructor.


class A
{
     int n ;
   public:
     void print();
     A(int m);//this is the constructor
     A();//this is default constructor
};
A::A()
{
      n = 0;
      cout<<"default constructor is called"<<endl;
}

After this correction, we will recompile our program and the output is
 
constructor is called for m=33
constructor is called for m=44
constructor is called for m=-3
default constructor is called


In the next post, we will see about copy constructor.

Comments

Popular Posts