Constructors and Destructors

Constructors

A constructor is a special function which can be included in a class. It is unusual as a function because it is never specifically called, the same way that other functions are. A constructor function is called automatically when the class variable is declared. It is used to set up the class variable with sensible values in the member variables. Take a look at this short program:

#include <iostream.h>

class daft
 { public:
    int x, y, z;
 };

daft my_variable;

void main ()
 {
   cout << my_variable.x << endl;
   cout << my_variable.y << endl;
   cout << my_variable.z << endl;
 }

The class contains only the minimum to make it viable - just three public variables. You will notice that the member variables x, y and z are not set up in any way before their values are displayed. An intelligent C++ compiler may even spot this and warn you. The result is that when the member variables are created, they will contain random numbers - whatever happened to be in those memory slots at that time. Now look at this rewritten program:

#include <iostream.h>

class daft
 { public:
    int x, y, z;

   daft ()
    { x = 23;
      y = 45;
      z = 133;
    }
 };

daft my_variable;

void main ()
 {
   cout << my_variable.x << endl;
   cout << my_variable.y << endl;
   cout << my_variable.z << endl;
 }

This program is identical to the one that you saw above except that a function definition has been added to the class. This function is unusual: it isn't qualified by the words public: or private:, nor does it have a return type (not even the word void). It also has the same name as the class type itself (daft). This is the constructor function.

The main program is exactly the same as it was in the first version of the program. However, when the variable my_variable is declared, the constructor function is automatically called. This sets the variables as shown, and these are the values which are displayed when the program is run. If you want, you can declare a constructor function with parameters:

#include <iostream.h>

class cuboid
 { public:
    double length, width, height;

   cuboid (double l_value, double w_value, double h_value)
    { length = l_value;
      width = w_value;
      height = h_value;
    }
 };

cuboid brick(27.0,10.0,7.5);
cuboid kerbstone(120.7,35.0,14.1);

void main ()
 { double volume = brick.height * brick.width * brick.length;
   cout << "The volume of the brick is " << volume " cubic cm." << endl;
   double weight;
   weight = kerbstone.length * kerbstone.width * kerbstone.height * 8.6;
   cout << "The weight of the kerbstone is " << weight << " g." << endl;
 }

In this case, the constructor is defined as having three parameters, so three parameters are provided when the class variables are declared, and the member variables are set up to be those values. This raises the interesting question: Can a class variable of type cuboid be declared without any parameters? Suppose you wanted to declare another variable, doorstop, but hadn't a clue what sort of dimensions it had, could you write a statement like this?

cuboid doorstop;

Yes, this would compile. The compiler would detect that the variable was being declared without any parameters. It would then look for a constructor which didn't take any parameters. The only constructor that it can find takes three parameters, so the compiler couldn't use that one for this variable. In that case, it declares the variable cuboid without using a constructor. The result is that the member variables of the variable cuboid are undefined just after it has been declared - we would have to then set them in the main program.

Overloading constructors

The logical extension to this is to ask: Is it possible to declare more than one constructor for a class, one with parameters, and one without? Well, yes. This is an example of function overloading, where more than one function with the same name is defined, each with a different number of parameters, and the compiler chooses different constructors on different occasions:

#include <iostream.h>
#include <string.h>

class test
 { public:
    int x;
    string message;

   // The first constructor has no parameters
   test ()
    { x = 23;
      message = "The no-parameter constructor was used.";
    }

   // The second constructor has 1 parameter
   test (int set_x_to_this)
    { x = set_x_to_this;
      message = "The 1-parameter constructor was used.";
    }
 };

void main ()
 { test test_class1;
   test test_class2(100);
   cout << test_class1.x << endl;
   cout << test_class1.message << endl;
   cout << test_class2.x << endl;
   cout << test_class2.message << endl;
 }

Destructors

You've probably guessed by now that a destructor is a special function that is called whenever a class variable is destroyed. It is used to tie up the loose ends nicely. This might involve freeing memory that was reserved for objects indicated by pointers (a typical use), or to ensure that any data held in the class was written safely to disc.

A destructor is declared as having the same name as the function, except that the name is preceded by the ~ symbol before it. Apart from that symbol, the declaration of a destructor would be indistinguishable from a constructor. Here is an example of a destructor being used:

#include <iostream.h>
#include <cstring.h>

class person
 { public:
    string name;

    // Here is the constructor
    person (string init)
    { name = init;
      cout << "Person " << name
           << " has just been initialised!"
           << endl;
    }

    // Here is the destructor
    ~person ()
    { cout << "Aaargh! " << name
           << " is about to die!" << endl;
    }
 };

void main ()
 { int count;
   for (count = 0; count < 4; count++)
    { string n;
      cout << "Please enter a name : ";
      cin >> n;
      person temp(n);
      cout << "The variable is in scope." << endl;
    }
 }

Please enter a name : Richard
Person Richard has just been initialised!
The variable is in scope.
Aaargh! Richard is about to die!
Please enter a name : Diane

etc.

In this case, the constructor sets up the name variable according to the string, and the destructor displays a message when the variable is about to be destroyed. The variable is destroyed at the end of each iteration of the loop, because it was declared within that loop, so it can only exist while that iteration of the loop is running. Every time the loop starts afresh, the class variable is created afresh, and the constructor and destructor are called again. We say that the class variable temp has scope during the loop iteration, and at the end of the loop, it goes out of scope and ceases to exist.


Go back
Top of the page
Main Menu
Questions
Worked Examples
Go on
Go back
Top of the page
Main Menu
Questions
Worked Examples
Go on