CONSTRUCTOR and the DESTRUCTOR in C++


The CONSTRUCTOR and the DESTRUCTOR can be used to initialise and destroy an instance of a class:

 

Very special and essential methods are the CONSTRUCTOR and DESTRUCTOR. They are automatically called whenever an instance of a class is created or destroyed (variable declaration, end of program, new, delete...). 

The constructor will initialize the variables of the instance, do some calculation, allocate some memory for the instance, output some text... whatever is needed. 

Here is an example of a class definition with two overloaded constructors: 

#include <iostream.h>

class vector
{
public:

double x;
double y;

vector () // same name as class
{
x = 0;
y = 0;
}

vector (double a, double b)
{
x = a;
y = b;
}

};

void main ()
{
vector k; // vector () is called

cout << "vector k: " << k.x << ", " << k.y << endl << endl;

vector m (45, 2); // vector (double, double) is called

cout << "vector m: " << m.x << ", " << m.y << endl << endl;

k = vector (23, 2); // vector created, copied to k, then
erased

cout << "vector k: " << k.x << ", " << k.y << endl << endl;
}

It is a good practice to try not to overload the constructors. Best is to declare only one constructor and give it default parameters wherever possible: 

#include <iostream.h>

class vector
{
public:

double x;
double y;

vector (double a = 0, double b = 0)
{
x = a;
y = b;
}
};

void main ()
{
vector k;
cout << "vector k: " << k.x << ", " << k.y << endl << endl;

vector m (45, 2);
cout << "vector m: " << m.x << ", " << m.y << endl << endl;

vector p (3);
cout << "vector p: " << p.x << ", " << p.y << endl << endl;
}


The destructor is often not necessary. You can use it to do some calculation whenever an instance is destroyed or output some text for debugging. But if variables of the instance point towards some allocated memory then the role of the destructor is essential: it must free that memory! Here is an example of such an application: 

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

class person
{
public:

char *name;
int age;

person (char *n = "no name", int a = 0)
{
name = new char[100]; // better than malloc!
strcpy (name, n);
age = a;
cout << "Instance initialized, 100 bytes allocated" << endl;
}

~person () // The destructor
{
delete (name); // instead of free!
cout << "Instance going to be deleted, 100 bytes freed" << endl;
}
};

void main ()
{
cout << "Hello!" << endl << endl;

person a;
cout << a.name << ", age " << a.age << endl << endl;

person b ("John");
cout << b.name << ", age " << b.age << endl << endl;

b.age = 21;
cout << b.name << ", age " << b.age << endl << endl;

person c ("Miki", 45);
cout << c.name << ", age " << c.age << endl << endl;

cout << "Bye!" << endl << endl;
}


Here is a short example of an array class definition. A method that is an overload of the [] operator and that outputs a reference (&) is used in order to generate an error if it is tried to access outside the limits of an array: 

#include <iostream.h>
#include <stdlib.h>

class array 
{
public:
int size;
double *data;

array (int s)
{
size = s;
data = new double [s];
}

~array ()
{
delete data;
}

double &operator [] (int i)
{
if (i < 0 || i >= size)
{
cerr << endl << "Out of bounds" << endl;
exit (EXIT_FAILURE);
}
else return data [i];
}
};

void main ()
{
array t (5); 

t[0] = 45; // OK
t[4] = t[0] + 6; // OK
cout << t[4] << endl; // OK

t[10] = 7; // error!
}





Added on July 14, 2007 Comment
}