Constructor and Destructor in C++

quiz
Challenge Inside! : Find out where you stand! Try quiz, solve problems & win rewards!

Overview

Constructor and Destructor are the special member functions of the class which are created by the C++ compiler or can be defined by the user. The constructor is used to initialize the object of the class while the destructor is called by the compiler when the object is destroyed.

Scope

  • This article covers the concepts of Constructors and Destructors in C++.
  • It covers the difference between Constructors and Destructors in C++.

Introduction to Constructor and Destructor in C++

While programming, sometimes there might be the need to initialize data members and member functions of the objects before performing any operations. Data members are the variables declared in any class by using fundamental data types (like int, char, float, etc.) or derived data types (like class, structure, pointer, etc.). The functions defined inside the class definition are known as member functions.

Suppose you are developing a game. In that game, each time a new player registers, we need to assign their initial location, health, acceleration, and certain other quantities to some default value.

This can be done by defining separate functions for each quantity and assigning the quantities to the required default values. For this, we need to call a list of functions every time a new player registers. Now, this process can become lengthy and complicated.

What if we can assign the quantities along with the declaration of the new player automatically? A constructor can help do this in a better and simpler way.

Moreover, when the player deletes his account, we need to deallocate the memory assigned to him. This can be done using a destructor.

What is a Constructor in C++?

A Constructor is a special member function of a class and shares the same name as of class, which means the constructor and class have the same name. Constructor is called by the compiler whenever the object of the class is created, it allocates the memory to the object and initializes class data members by default values or values passed by the user while creating an object. Constructors don’t have any return type because their work is to just create and initialize an object.

Syntax of Constructor:

class scaler {
  public:
    // Constructor
    scaler() { 
   // Constructor body.
    }
};

Characteristics of Constructors in C++

  • A constructor can be made public, private, or protected per our program's design. Constructors are mostly made public, as public methods are accessible from everywhere, thus allowing us to create the object of the class anywhere in the code. When a constructor is made private, other classes cannot create instances of the class. This is used when there is no need for object creation. Such a case arises when the class only contains static member functions(i.e., the functions which are independent of any class object and can be accessed using a class name with scope resolution operator, i.e. ::).

  • A constructor in C++ cannot be inherited. However, a derived class can call the base class constructor. A derived class(i.e., child class) contains all members and member functions(including constructors) of the base class.

  • Constructor functions are not inherited, and their addresses cannot be referenced.

  • The constructor in C++ cannot be virtual. A virtual table(also called vtable) is made for each class having one or more virtual functions. Virtual functions ensure that the correct function is called for an object regardless of the type of reference used for the function call. Whenever an object is created of such a class, it contains a ‘virtual-pointer’ that points to the base of the corresponding vtable. Whenever there is a virtual function call, the vtable refers to the function address.

But when a class constructor is executed, there is no virtual table created yet in the memory, meaning no virtual pointer is defined yet. As a result, a constructor cannot be declared virtual.

Types of Constructors in C++

There are four types of constructors in C++:

  1. Default Constructors
  2. Parameterized Constructors
  3. Copy Constructors
  4. Dynamic Constructors

1. Default Constructor:

A constructor which does not receive any parameters is called a Default Constructor or a Zero Argument Constructor. Every class object is initialized with the same set of values in the default constructor.

Even if a constructor is not defined explicitly, the compiler will provide a default constructor implicitly.

Syntax:

//default constructor without any arguments
Employee :: Employee()   

Example:

class Employee {
  public:
    int age;
  
    // Default constructor.
    Employee() {
      /* Data member is defined with the help of the 
      default constructor.*/
      age = 50;
    }
};

int main() {
  // Object of class Employee declared.
  Employee e1;
  // Prints value assigned by default constructor.
  cout << e1.age;
  return 0;
}

Output:

50

Note: Default constructor provided by the compiler will be called, which will initialize the object data members to the default value, which will be 0 or any random integer value in the example provided below.

Example:

Considering the previous example, the default constructor (i.e., Employee() in Employee class definition) defined by the programmer assigns the data member age to a value of 50.

But in the given example here, as the data member age is not assigned to any value, the compiler calls the default constructor, and age is initialized to 0 or unpredictable garbage values.

class Employee {
  public:
    int age;
    // Default constructor not defined.
    // Compiler calls default constructor.
};

int main() {
  // Object e1 declared.
  Employee e1; 
  cout << e1.age;
  return 0;
}

Output:

0

2. Parameterized Constructor

Using the default constructor, it is impossible to initialize different objects with different initial values. What if we need to pass arguments to constructors which are needed to initialize an object? There is a different type of constructor called Parameterized Constructor to solve this issue.

A Parameterized Constructor is a constructor that can accept one or more arguments. This helps programmers assign varied initial values to an object at the creation time.

Example:

#include <iostream>

using namespace std;

class Employee {
  public:
    int age;
    // Parameterized constructor
    Employee(int x) { 
    /* Age assigned to value passed as an argument 
    while object declaration.*/
      age = x; 
    }
};

int main() {
  /* Object c1 declared with argument 40, which 
  gets assigned to age.*/
  Employee c1(40); 
  Employee c2(30);
  Employee c3(50);
  cout << c1.age << "\n";
  cout << c2.age << "\n";
  cout << c3.age << "\n";
  return 0;
}

Output:

40
30
50

3. Copy Constructor

A Copy constructor is a type of constructor used to create a copy of an already existing object of a class type. The compiler provides a default Copy Constructor to all the classes. A copy constructor comes into the picture whenever there is a need for an object with the same values for data members as an already existing object. A copy constructor is invoked when an existing object is passed as a parameter.

Syntax:

//Copy constructor
Employee :: Employee(Employee &ptr)        

Example:

#include<iostream>
using namespace std;

class Employee {
  private:
    // Data members
    int salary, experience; 

  public:
    // Parameterized constructor
    Employee(int x1, int y1) { 
      salary = x1;
      experience = y1;
    }

    // Copy constructor
    Employee(const Employee &new_employee) {
      salary = new_employee.salary;
      experience = new_employee.experience;
    }

    void display() {
      cout << "Salary: " << salary << endl;
      cout << "Years of experience: " << experience << endl;
    }
};

// main function 
int main() {
  // Parameterized constructor
  Employee employee1(34000, 2); 
  // Copy constructor
  Employee employee2 = employee1; 
  cout << "Employee1 using parameterized constructor : \n";
  employee1.display();
  cout << "Employee2 using copy constructor : \n";
  employee2.display();
  return 0;
}

Output:

Employee1 using the parameterized constructor : 
Salary: 34000
Years of experience: 2
Employee2 using copy constructor : 
Salary: 34000
Years of experience: 2

Explanation:

In this example, object employee1 of class Employee is declared in the first line of the main() function. The data members salary and experience for object employee1 are assigned 34000 and 2, respectively, with the help of a parameterized constructor, which is invoked automatically. When object employee2 is declared in the second line of the main() function, object employee1 is assigned to employee2, which invokes the copy constructor as the argument here is an object itself. As a result, the data member's salary and experience of object employee2 are assigned to values possessed by the salary, and experience data members of object employee1 (i.e., 34000, 2), respectively.

4. Dynamic Constructor

When the allocation of memory is done dynamically (i.e., Memory is allocated to variables at run-time of the program rather than at compile-time) using a dynamic memory allocator new in a constructor, it is known as a Dynamic constructor. By using this, we can dynamically initialize the objects.

#include <iostream>
using namespace std;

class Employee {
  int* due_projects;

  public:
    // Default constructor.
    Employee() {
    // Allocating memory at run time.
      due_projects = new int;
      *due_projects = 0;
    }

    // Parameterized constructor.
    Employee(int x) {
      due_projects = new int;
      *due_projects = x;
    }
    
    void display() {
      cout << *due_projects << endl;
    }
};

//main function 
int main() {
  // Default constructor would be called.
  Employee employee1 = Employee();
  cout << "Due projects for employee1:\n";
  employee1.display();

  // Parameterized constructor would be called.
  Employee employee2 = Employee(10);
  cout << "Due projects for employee2:\n";
  employee2.display();
  return 0;
}

Output:

Due projects for employee1:
0
Due projects for employee2:
10

Explanation:

Here, integer type pointer variable is declared in class which is assigned memory dynamically when the constructor is called. When we create object employee1 of class Employee in the first line of the main() function, the default constructor(i.e. Employee() in class Employee definition) is called automatically, and memory is assigned dynamically to the pointer type variable(i.e., *due_projects) and initialized with value 0.

And similarly, when employee2 is created in the third line of the main() function, the parameterized constructor(i.e., Employee(int x) in the class definition) is called, and memory is assigned dynamically.

What is a Destructor in C++?

A Destructor is a member function that is instantaneously called whenever an object is destroyed. The destructor is called automatically by the compiler when the object goes out of scope, i.e., when a function ends, the local objects created within it are also destroyed. The destructor has the same name as the class name, but the name is preceded by a tilde(~). A destructor has no return type and receives no parameters.

Syntax of Destructor:

class scaler {
  public:
   //constructor
    scaler();
   //destructor
    ~scaler(); 
};

Characteristics of a Destructor in C++

  • A destructor deallocates memory occupied by the object when it’s deleted.

  • A destructor cannot be overloaded. In function overloading, functions are declared with the same name in the same scope, except that each function has a different number of arguments and different definitions. But in a class, there is always a single destructor that does not accept any parameters. Hence, a destructor cannot be overloaded.

  • A destructor is always called in the reverse order of the constructor. In C++, variables and objects are allocated on the Stack. The Stack follows the LIFO (Last-In-First-Out) pattern. So, the deallocation of memory and destruction is always carried out in the reverse order of allocation and construction. This can be seen in the code below.

  • A destructor can be written anywhere in the class definition. But to bring an amount order to the code, a destructor is always defined at the end of the class definition.

Implementation of Constructors and Destructors in C++

#include <iostream>

using namespace std;
class Department {

  public:
    Department() {
      // Constructor is defined.
      cout << "Constructor Invoked for Department class" << endl;
    }
    
    ~Department() {
      // Destructor is defined.
      cout << "Destructor Invoked for Department class" << endl;
    }
};
class Employee {

  public:
    Employee() {
      // Constructor is defined.
      cout << "Constructor Invoked for Employee class" << endl;
    }
    
    ~Employee() {
      // Destructor is defined.
      cout << "Destructor Invoked for Employee class" << endl;
    }
};
int main(void) {
  // Creating an object of Department.
  Department d1; 
  // Creating an object of Employee.
  Employee e2; 
  return 0;
} 

Output:

Constructor Invoked for Department class
Constructor Invoked for Employee class
Destructor Invoked for Employee class
Destructor Invoked for Department class

Explanation:

When an object named d1 is created in the first line of main(), i.e. (Department d1), its constructor is automatically invoked during the creation of the object. As a result, the first line of output, “Constructor Invoked for Department class,” is printed. Similarly, when the e2 object of the Employee class is created in the second line of main(), i.e. (Employee e2), the constructor corresponding to e2 is invoked automatically by the compiler, and “Constructor Invoked for Employee class” is printed.

A destructor is always called in reverse order as that of a constructor. When the scope of the main function ends, the destructor corresponding to object e2 is invoked first. This leads to printing “Destructor Invoked for Employee class”. Lastly, the destructor corresponding to object d1 is called, and “Destructor Invoked for Department class” is printed.

Difference Between Constructors and Destructors

S. No.ConstructorsDestructors
1Constructor is invoked to initialize the object of a class by the compiler.Destructor is invoked when the instance is destroyed.
2Declared as Class_Name(arguments if any){//constructor body}.Declared as ~Class_Name(){}.
3Constructor can receive parameters.Destructor cannot accept any parameters.
4Constructor is used to initialize an object of the class and assign values to data members corresponding to the class.While destructor is used to deallocate the memory of an object of a class.
5There can be multiple constructors for the same class.In a class, there is always a single destructor.
6Constructor can be overloaded.Destructor can’t be overloaded.

Conclusion

  • Constructors are an essential part of a class definition and should be designed and built with care as these functions define how new class objects are to be instantiated. They allow us to create different instances of our classes.

  • A constructor which does not receive any parameters is called a Default Constructor or a Zero Argument Constructor.

  • A Parameterized Constructor is a constructor that can accept one or more arguments.

  • A Copy constructor is a type of constructor used to create a copy of an already existing object of a class type.

  • When the allocation of memory is done dynamically using a dynamic memory allocator new in a constructor, it is known as a Dynamic constructor.

  • A Destructor deallocates memory occupied by the object when it’s deleted.

Challenge Time!
quiz
quiz
Time to test your skills and win rewards! Note: Rewards will be credited after the next product update.
Free Courses by top Scaler instructors
rcbGet a Free personalized Career Roadmap from