Constructors and Destructors

 Constructors and destructors in C++

Classes provide a special way of initializing objects – through the use of constructors. Similarly certain commands can be exeuted before any object is deleted- this is done via destructors.


a few notes on constructors/ destructors

  • constructors and destructors do not have return types (not even void) nor can they return values.
  • references and pointers cannot be used on constructors and destructors because their addresses     cannot be taken.
  • constructors and destructors cannot be declared static, const
  • constructors and destructors obey the same access rules as member functions.
  • Like other member functions, constructors and destructors are declared within a class declaration.  They can be defined inline or external to the class declaration. 
  • Derived classes do not inherit constructors or destructors from their base classes, but they do call the constructor and destructor of base classes.

 

Constructor

 

A constructor is a member function of the class that is called automatically whenever an object is created.

 

  •   constructors cannot be declared with the keyword virtual.
  •  a constructor does not allocate memory for the class object. It simply initializes the members of that object
  • constructor name is same as that of the class it belongs to

 

Overloaded constructors

Just the  way we have function overloading , we can overload constructors as well.

 

The following example demonstrates the use of constructor in different forms 

EXAMPLE 1

#include<iostream>
using namespace std;

class STUDENT
        {

            int  age;
           int rollno;
           float perc;
        public:

            int input();
            int output();

            STUDENT()
            {
            cout<<endl<<"Constructor 1"<<endl;
            perc=0;
            rollno=0;
            age=0;
            }

            STUDENT(int roll)
            {
            cout<<endl<<"Constructor 2"<<endl;
            rollno=roll;

            age=0;perc=0;
            }
            STUDENT(int roll, int AGE)
            {
            cout<<endl<<"Constructor 3"<<endl;
            rollno=roll;
            age=AGE;
            perc=0;
            }
            STUDENT(int roll,float PERC)
            {
            cout<<endl<<"Constructor 4"<<endl;
            rollno=roll;
            age=0;
            perc=PERC;
            }
            ~STUDENT()
            {

            cout<<endl<<"destructor at work\t"
                <<"roll no : "<<rollno<<endl;
            }

        };

int STUDENT::input()
{
    cout<<endl;
    cout<< "Enter Roll number :: ";
    cin>>rollno;
 cout<<"ENter perc :: ";
    cin>>perc;
    cout<<"ENter age :: ";
    cin>>age;

return 1;
}
int STUDENT::output()
{
    cout<<endl;
    cout<<endl<<"Roll number\t::\t"<<rollno;
    cout<<endl<<"Age\t\t::\t"<<age;
    cout<<endl<<"Perc. \t\t::\t"<<perc;

return 1;
}

int main()
{
STUDENT  a=STUDENT();
STUDENT  b(12);
STUDENT  c(13,66);
STUDENT  d(14,5.66F);
STUDENT  *e;
e=new STUDENT(34,6);
a.output();
b.output();
c.output();
d.output();
e->output();
cout<<"\ndeleting e"<<endl;
delete(e);
cout<<endl<<"e deleted"<<endl;
return 1;
}
OUTPUT
Constructor 1

Constructor 2

Constructor 3

Constructor 4

Constructor 3


Roll number     ::      0
Age             ::      0
Perc.           ::      0

Roll number     ::      12
Age             ::      0
Perc.           ::      0

Roll number     ::      13
Age             ::      66
Perc.           ::      0

Roll number     ::      14
Age             ::      0
Perc.           ::      5.66

Roll number     ::      34
Age             ::      6
Perc.           ::      0
deleting e

destructor at work      roll no : 34

e deleted

destructor at work      roll no : 14

destructor at work      roll no : 13

destructor at work      roll no : 12

destructor at work      roll no : 0

Process returned 1 (0x1)   execution time : 0.094 s
Press any key to continue.

 

in the above program

- we have declared four constructors 

o with no argument

o with one argument

o two overloaded constructors with two arguments each

- for invoking the required constructors

two formats can be used

   -   a=STUDENT(parameter list)   or simply a(parameter list)

- the use of destructors has also been shown. The output also shows that objects are deleted in the reverse order in which they are created

 

REMARK

You can call a constructor only while creating a object and not afterwards

STUDENT  a ;

a(34,5);              //this will result in an error

 

NOTE

If you DO NOT DECLARE your own constructor/destructor the compiler automatically creates a default one . This default constructor initializes the members to some garbage value.

 In fact these are not the only members that the compiler creates automatically. The other two are the copy constructor and copy assignment operator.

 

Copy constructors

This is one elusive aspect of the constructors. 

This constructor is automatically invoked whenever a copy of a object is required to be created

consider the following two statements

 

STUDENT obj1=obj2;

STUDENT obj1(obj2);

 

The first statement looks familiar. It copies obj2 to obj1 member wise. What is unknown here is that operator overloading is being used here to overload the assignment operator. Further details on this are being omitted for clarity and will be dealt later on.

 

The second statement also performs the same task, it copies obj2 into obj1 member-wise. This is the copy constructor.

The declaration of copy constructor is as follows

class_name(class_name &)

 

REMARK

The argument to copy constructor is always passed by reference. If this is not the case then a “out of memory “ error occurs. This is because if we had used call by value then for creating copies of the argument , again copy constructor would be called, and this would recursively continue till we run out of memory.

 

The copy constructor is always invoked for creating the copies of the argument

 whenever we pass a class object as argument to any function 

It may seem that the copy constructor is not required. But the following program illustrates the use of copy constructor.

 

EXAMPLE 2


#include<iostream>
using namespace std;

class STUDENT
        {

            int  age;
           int rollno;
        public:

            int input();
            int output();

            STUDENT()
            {
            cout<<endl<<"Constructor 1"<<endl;
            rollno=age=0;
            }

            STUDENT(int roll, int AGE)
            {
            cout<<endl<<"Constructor 2"<<endl;
            rollno=roll;
            age=AGE;
            }
            STUDENT(STUDENT&)
            {
            cout<<endl<<"copy constructor at work"<<endl;
            }

        };

int STUDENT::input()
{
    cout<<endl;
    cout<< "Enter Roll number :: ";
    cin>>rollno;
    cout<<"ENter age :: ";
    cin>>age;

return 1;
}
int STUDENT::output()
{
    cout<<endl<<"Roll number\t::\t"<<rollno;
    cout<<endl<<"Age\t\t::\t"<<age;

return 1;
}

void display(STUDENT a);
void display_ref(STUDENT &a);
int main()
{
STUDENT  a;
STUDENT  b(13,66);

display(a);
display_ref(b);

return 1;
}

void display(STUDENT a)
{
a.output();
}

void display_ref(STUDENT &a)
{
a.output();
}

 
 

OUTPUT

 


Constructor 1

Constructor 2

copy constructor at work

Roll number     ::      2359092
Age             ::      4249040
Roll number     ::      13
Age             ::      66
Process returned 1 (0x1)   execution time : 0.063 s
Press any key to continue.

 

this program shows the copy constructor in action.

When we call the function display() , since it is a call be value , a copy of the argument object is required which invokes the copy constructor. 

In the display_ref() , call by reference is used , so no need for copy constructor

 

 

 

Destructor

 

  • You don't call them explicitly (they are called automatically for you), and there's only one destructor for each object. 
  • The name of the destructor is the name of the class, preceeded by a tilde (~)
  • Destructors can be declared with the keyword virtual.
  • A destructor does not de-allocate memory for the class object . It simply executes the commands in its definition just before its associated object  is about to be deleted.

 

 

 

If some object has been created using new() operator then it will be deleted  only when delete() is used and only then will its destructor be called.