C++ Class Constructor and Destructor

Constructor and destructor functions are essential components of object-oriented programming in C++. Constructors initialize objects when they are created, and destructors clean up resources before an object is destroyed. This tutorial explores the concepts, types, and best practices associated with constructor and destructor functions in C++.

C++ Constructor Function

A constructor is a special member function of a class that is automatically called when an object of the class is created. Its primary purpose is to initialize the object's data members and set up the object's state.

The declaration of a constructor function is similar to any other member function except the name of the function must match the class name and without any return type not even void.

Constructor functions are mainly used for initialization of member variables and for doing some pre-processing. If we don't define any constructor function then C++ compiler automatically created a default constructor.

#include 
using namespace std;

class Box {
   // Member Variables 
   private:
     int length;
     int width; 
     int height;
     
   // Member Functions 
   public:   
  // Constructor
     Box() {
       cout << "Inside Constructor function\n";
         length = 5;
  width = 6;
  height = 4;
     }
  
     void setData(int L, int W, int H) {
         length = L;
  width = W;
  height = H;
     }
  
     int getBaseArea() {
         return length * width;  
     } 

     int getVolume() {
         return length * width * height;   
     }
};

int main() {
 // Creating Object of class Box 
 Box b1;
 
 cout << "Base Area of Box : " << b1.getBaseArea();
 cout << "\nVolume of Box : " << b1.getVolume(); 
 
    return 0;
}
Output
Inside Constructor function
Base Area of Box : 30
Volume of Box : 120

In above program, Box() member function is constructor of class Box. Inside constructor we are initializing member variables of Box with some default value. When we are declaring object "b1" constructor function gets called automatically and printed "Inside Constructor function" message on screen and initialized length, width and height data members of object b1.

We are calling getBaseArea() function to calculate the base area of box because we cannot directly access private data members of box class. Member variables length, width and height can only be accessed from an internal class member function.

Default Constructor

A default constructor is one that takes no parameters. If a class doesn't have any constructor defined, C++ provides a default constructor automatically.

class MyClass {
public:
    // Default constructor 
    // (implicitly provided by the compiler)
};

Parameterized Constructor

In above example, the constructor function Box() doesn't take any input argument. If we want we can pass parameters to constructor during object declaration for initialization of member variables of object.

#include <iostream>
using namespace std;

class Box {
   // Member Variables 
   private:
     int length;
     int width; 
     int height;
     
   // Member Functions 
   public:   
     // Parameterized Constructor
     Box(int L, int W, int H) {
       cout << "Inside Constructor function\n";
         length = L;
      width = W;
      height = H;
     }

    int getVolume() {
        return length * width * height;   
    }
};

int main() {
    // Creating Objects 
    Box b1(4, 5, 6);
    Box b2(1, 2, 3);

    cout << "Volume of Box 1 : " << b1.getVolume() << endl; 
    cout << "Volume of Box 2 : " << b2.getVolume(); 
 
    return 0;
}
Output
Inside Constructor function
Inside Constructor function
Volume of Box 1 : 120
Volume of Box 2 : 6

In above program, we defined a parameterized constructor Box(int L, int W, int H) which takes three integers as arguments. While object declaration we are passing initial values of member variables enclosed in bracket after object name. This declaration will invoke parameterized constructor which in turn will set the values of member variables.

Copy Constructor

A copy constructor creates a new object as a copy of an existing object. It is invoked when an object is passed by value or explicitly when creating a new object from an existing one.

class Student {
private:
    string name;
    int age;

public:
    // Copy constructor
    Student(const Student& other) {
        name = other.name;
        age = other.age;
    }
};

Constructor Overloading in C++

We can overload constructor functions also like overloading of any other function in C++. All over loaded constructors will have the same name but either their number of parameters are different or their parameters are of a different data type. Depending upon the number and type of the arguments passed during object declaration, compiler will select appropriate version of constructor.

When we declare overloaded parameterized constructors then we also have to declare a constructor without any parameter(default constructor) so that we can create objects without passing any initial value.

#include <iostream>
using namespace std;

class Box {
   // Member Variables 
   private:
     int length;
     int width; 
     int height;
     
   // Member Functions 
   public:   
     Box() {
      cout << "Inside Default Constructor function\n";
      length = width = height = 0;
  }
  
     Box(int L, int W) {
       cout << "Inside Constructor one function\n";
         length = L;
      width = W;
      height = 0;
  }
 
     Box(int L, int W, int H) {
       cout << "Inside Constructor two function\n";
         length = L;
      width = W;
      height = H;
  }

     int getVolume() {
         return length * width * height;   
  }
};

int main() {
 // Creating Objects 
 Box b1;
 Box b2(4, 5);
 Box b3(1, 2, 3);

 cout << "Volume of Box 1 : " << b1.getVolume() << endl; 
 cout << "Volume of Box 2 : " << b2.getVolume()<< endl; 
 cout << "Volume of Box 3 : " << b3.getVolume(); 
  
    return 0;
}
Output
Inside Default Constructor function
Inside Constructor one function
Inside Constructor two function
Volume of Box 1 : 0
Volume of Box 2 : 0
Volume of Box 3 : 6 
In above program, we have written three overloaded constructor of class Box.
Box(); // NO parameter 
Box(int L, int W); // Two Parameters
Box(int L, int W, int H); // Three Parameters
and defining three object of Box class by passing different parameters.
  • Box b1; For object b1, default constructor gets called.
  • Box b2(4, 5); For object b2 Box(int L, int W) constructor gets called.
  • Box b3(1, 2, 3); For object b3, Box(int L, int W, int H) constructor gets called.

C++ Destructor Function

  • Destructor functions are special member functions of a class that gets executed automatically whenever any object goes out of scope or gets deleted.
  • The name of the destructor function matches exactly with the name of the class prefixed with a tilde (~).
  • A destructor function can neither return any value nor it take any input parameters.
  • Destructor functions are best candidate for doing some post processing and releasing resources before coming out of the program like closing files, closing sessions etc.
#include <iostream>
using namespace std;

class Box {
   // Member Variables 
   private:
     int length;
     int width; 
     int height;
     
   // Member Functions 
   public:   
 
     Box(int L, int W, int H) {
       cout << "Inside Constructor function\n";
         length = L;
         width = W;
         height = H;
     }

     int getVolume() {
         return length * width * height;   
     }
  
     // Destructor function 
     ~Box() {
         cout << "Inside Destructor function";
     }
};

int main() {
 // Creating Object
 Box b(1, 2, 3);

 cout << "Volume of Box : " << b.getVolume() << endl; 
  
    return 0;
}
Output
Inside Constructor function
Volume of Box : 6
Inside Destructor function

Constructor and Destructor Invocation Order

  • Order of Constructor Invocation : When an object is created, the constructors of its base classes are called first, followed by the constructor of the derived class. This ensures that the base class is properly initialized before the derived class.
    class Base {
    public:
        Base() {
            cout << "Base constructor" << endl;
        }
    };
    
    class Derived : public Base {
    public:
        Derived() {
            cout << "Derived constructor" << endl;
        }
    };
    
    Creating an object of the Derived class will invoke the constructor of the Base class first, and then the constructor of the Derived class:

  • Order of Destructor Invocation : The order of destructor invocation is the reverse of the order of constructor invocation. When an object is destroyed, the destructor of the derived class is called first, followed by the destructor of the base class.
    class Base {
    public:
        ~Base() {
            cout << "Base destructor" << endl;
        }
    };
    
    class Derived : public Base {
    public:
        ~Derived() {
            cout << "Derived destructor" << endl;
        }
    };
    
    Destroying an object of the Derived class will invoke the destructor of the Derived class first, and then the destructor of the Base class

Conclusion

Constructor and destructor functions are fundamental aspects of C++ programming, contributing to the creation, initialization, and cleanup of objects. Constructors handle the setup of an object, ensuring it is in a valid state, while destructors perform cleanup operations before an object is destroyed.

Understanding the types of constructors (default, parameterized, copy) and the role of destructors in managing resources is crucial for writing robust and maintainable C++ code. By following best practices and considering resource management principles, developers can create classes that are not only effective but also adhere to the principles of modern C++ programming.