Friday, 8 May 2026

Constructors Under Inheritance in C++

Constructors Under Inheritance in C++
It has already been pointed out that whenever an object of a class is created, a constructor member function is invoked automatically and when an object of the derived class is created, the constructor for that object is called. This is due to the object of the derived class which contains the members of the base class also. Since the base class is also part of the derived class, it is not logical to call the constructors of the base class.

Example 1.
A program to demonstrate how to defi ne and declare a constructor member function in the base class as well as in the derived class under the inheritance mechanism.

//constructors under inheritance
#include <iostream>
using namespace std;
class baseA {
public:
baseA(); //constructor
};
class derivedB: public baseA {
public :
derivedB(); //constructor
};
baseA :: baseA()
{
cout << “ base class constructor \n”;
}
derivedB :: derivedB()
{
cout << “ derived class constructor \n”;
}
int main()
{
derivedB objb;
return 0;
}
Output of the above program
base class constructor
derived class constructor

Noe:-The above program consists of two constructors baseA() and derivedB(). Whenever an object objb is created, the constructors of the base classes are automatically invoked. C++ fi res the constructor from the lowest to the highest class. Before creating derivedB(), C++ executes baseA(). The constructor of base class is therefore executed before the constructor of the derived class.

Example 2.
A program to illustrate how to defi ne and declare a constructor member function under multiple inheritance technique.

//constructors under inheritance
#include <iostream>
using namespace std;
class baseA {
public:
baseA(); //constructor
};
class derivedB: public baseA {
public:
derivedB(); //constructor
};
class derivedC: public derivedB {
public :
derivedC(); //constructor
};
class derivedD: public derivedC{
public:
derivedD(); //constructor
};
baseA :: baseA()
{
cout << “ base class\n”;
}
derivedB :: derivedB()
{
cout << “ derivedB class \n”;
}
derivedC :: derivedC()
{
cout << “ derivedC class \n”;
}
derivedD :: derivedD()
{
cout << “ derivedD class \n”;
}
int main()
{
derivedD objd;
return 0;
}
Output of the above program
base class
derivedB class
derivedC class
derivedD class

DESTRUCTORS UNDER INHERITANCE
It has been seen that destructor is a special member function. It is invoked automatically to free the memory space which was allocated by the constructor functions. Whenever an object of the class is getting destroyed, the destructors are used to free the heap area so that the free memory space may be used subsequently. In the previous section, it has been demonstrated that constructors in an inheritance hierarchy fi refrom a base class to a derived class. Destructors in an inheritance hierarchy fi re from a derived class to a base class order, i.e., they fi re in the reverse order of that of the constructors.

Example 3.
A program to demonstrate how the destructor member function gets fi red from the derived class objectsto the base class objects through pointers.

//destructors under inheritance
#include <iostream>
using namespace std;
class baseA {
public:
~baseA(); //destructor
};
class derivedB: public baseA {
public:
~derivedB(); //destructor
};
baseA :: ~baseA()
{
cout << “ base class destructor\n”;
}
derivedB :: ~derivedB()
{
cout << “ derivedB class destructor \n”;
}
int main()
{
derivedB objb;
return 0;
}
Output of the above program
derivedB class destructor
base class destructor

Example 4.
A program to demonstrate how to defi ne, declare and invoke the destructor member functions under multiple inheritance.

//destructors under inheritance
#include <iostream>
using namespace std;
class baseA {
public :
~baseA(); //destructor
};
class derivedB: public baseA {
public:
~derivedB(); //destructor
};
class derivedC: public derivedB {
public:
~derivedC(); //destructor
};
class derivedD: public derivedC{
public:
~derivedD(); //destructor
};
baseA :: ~baseA()
{
cout << “ base class\n”;
}
derivedB :: ~derivedB()
{
cout << “ derivedB class \n”;
}
derivedC :: ~derivedC()
{
cout << “ derivedC class \n”;
}
derivedD :: ~derivedD()
{
cout << “ derivedD class \n”;
}
int main()
{
derivedD objd;
return 0;
}
Output of the above program
derivedD class
derivedC class
derivedB class
base class

Example 5.
A program to display the message of both constructors and destructors of a base class and a derived class.

//destructor under inheritance
#include <iostream>
using namespace std;
class baseA {
public:
baseA() { //baseA’s constructor
cout << “ base class constructor\n”;
}
~baseA() { //baseA’s destructor
cout << “ base class destructor\n”;
}
};
class derivedD: public baseA {
public:
derivedD() { //derivedD’s constructor
cout << “ derived class constructor\n”;
}
~derivedD() { //derivedD’s destructor
cout << “ derived class destructor\n”;
}
};
int main()
{
derivedD obj;
return 0;
}
Output of the above program
base class constructor
derived class constructor
derived class destructor
base class destructor

Note:-A destructor’s main job is to free the storage a computer dynamically allocates. By fi ring in the reverse order of constructors, destructors ensure that the most recently allocated storage is the fi rst storage to be freed. The following program explains how destructror member functions free the memory space which was allocated by the new operator.

Example 6.
A program to allocate the heap memory area using a constructor member function and to free the memory storage by the destructors under multiple inheritance system.

// destructor member function under inheritance
#include <iostream>
using namespace std;
class baseA {
private:
char *ptrbase;
public:
baseA();
~baseA();
};
class derivedD: public baseA {
private:
char *ptrderived;
public:
derivedD();
~derivedD();
};
baseA:: baseA() //baseA’s constructor
{
ptrbase = new char[5];
cout << “ Base class allocates 5 bytes \n”;
}
baseA :: ~baseA() //baseA’s destructor
{
delete[] ptrbase;
cout << “ base class frees 5 bytes \n”;
}
derivedD::derivedD() //derivedD’s constructor
{
ptrderived = new char[100];
cout << “ Derived class allocates 100 bytes \n”;
}
derivedD :: ~derivedD()
{
delete[] ptrderived;
cout << “ Derived class frees 100 bytes \n”;
}
int main()
{
baseA *ptr = new derivedD;
delete ptr;
return 0;
}
Output of the above program
Base class allocates 5 bytes
Derived class allocates 100 bytes
base class frees 5 bytes

VIRTUAL DESTRUCTORS
It is known that the destructor member function is invoked to free the memory storage by the C++ compiler automatically. But the destructor member function of the derived class is not invoked to free the memory storage which was allocated by the constructor member function of the derived class. It is because the destructor member functions are non-virtual and the message will not reach the destructor member functions under late binding. So it is better to have a destructor member function as virtual and the virtual destructors are essential in a program to free the memory space effectively under late binding method. he following program segment illustrates how to defi ne a virtual destructor in a program.

// virtual destructor
class baseA {
public:
baseA();
//constructor cannot have virtual
virtual ~baseA();
};
class derivedD: public baseA {
-------
-------
};
baseA :: ~baseA() //baseA’s destructor
{
delete[] ptrbase;
cout << “ base class frees 5 bytes \n”;
}
int main()
{
baseA *ptr = new derivedD;
delete ptr;
}
Note:- Note that whenever instances are created at run time on the heap through the new operator, constructor member functions are called automatically. When the delete operator is used, the destructors are automatically called to release the space occupied by the instance itself. As a derived class instance always contains a base class instance, it is necessary to invoke destructors of both the classes in order to ensure that all the space on the heap is released.

Example 7.
A program to illustrate how a block of memory space which are allocated by new operators and released when destructor member functions are called.

// virtual destructor
#include <iostream>
using namespace std;
class baseA {
private:
char *ptrbase;
public:
baseA(); //constructor cannot have virtual
virtual ~baseA();
};
class derivedD: public baseA {
private:
char *ptrderived;
public:
derivedD();
~derivedD();
};
baseA:: baseA() //baseA’s constructor
{
ptrbase = new char[5];
cout << “ Base class allocates 5 bytes \n”;
}
baseA :: ~baseA() //baseA’s destructor
{
delete[] ptrbase;
cout << “ base class frees 5 bytes \n”;
}
derivedD::derivedD() //derivedD’s constructor
{
ptrderived = new char[100];
cout << “ Derived class allocates 100 bytes \n”;
}
derivedD :: ~derivedD()
{
delete[] ptrderived;
cout << “ Derived class frees 100 bytes \n”;
}
int main()
{
baseA *ptr = new derivedD;
delete ptr;
return 0;
}
Output of the above program
Base class allocates 5 bytes
Derived class allocates 100 bytes
Derived class frees 100 bytes
base class frees 5 bytes

Example 8.
A program to demonstrate how to defi ne, declare and invoke the virtual destructor member function in multiple inheritance using the polymorphic technique.

//non-virtual destructor function
#include <iostream>
using namespace std;
class base {
public:
void display();
~base();
};
class derived: public base
{
public:
void display();
~derived();
};
void base :: display()
{
cout << “ Base class member function”;
cout << endl;
}
base :: ~base()
{
cout << “ base class destructor is called ”;
cout << endl;
}
void derived :: display()
{
cout << “ Derived class member function”;
cout << endl;
}
derived :: ~derived()
{
cout << “ derived class destructor is called ”;
cout << endl;
}
int main()
{
base *ptr = new derived;
ptr->display(); // same method is called for both base class
// and derived class
delete ptr;
return 0;
}
Output of the above program
Base class member function
base class destructor is called

Example 9.
A program to illustrate how to defi ne and declare a class which consists of both virtual members and virtual destructors under multiple inheritance.

//virtual destructor function
#include <iostream>
using namespace std;
class base {
public:
virtual void display ();
virtual ~base(); //destructor member function
};
class derived: public base
{
public:
virtual void display ();
virtual ~derived(); //destructor member function
};
void base :: display()
{
cout << “ Base class member function”;
cout << endl;
}
base :: ~base()
{
cout << “ base class destructor is called ”;
cout << endl;
}
void derived :: display()
{
cout << “ Derived class member function”;
cout << endl;
}
derived :: ~derived()
{
cout << “ derived class destructor is called ”;
cout << endl;
}
int main()
{
base *ptr = new derived;
ptr->display(); // same method is called for both base class
// and derived class
delete ptr;
return 0;
}
Output of the above program
Derived class member function
derived class destructor is called
base class destructor is called

0 comments

Post a Comment