Search for Courses, Topics
certificate icon
Certificate

Learn on Scaler Topics and get certified.

static-certificate

Constructor and Destructor in C++

Learn about Constructor and Destructor in C++

5 Aug 2021-11 mins read
quiz
Challenge Inside! : Find out where you stand! Try quiz, solve problems & win rewards!

Overview

Constructor in C++ is a special member function of a class whose task is to initialize the object of the class. A destructor is also a member function of a class that is instantaneously called whenever an 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 for the initialization of data members and member functions of the objects before performing any operations on them. Data members are the variables that are declared in any class by using any fundamental data types (like int, char, float, etc) or derived data types (like class, structure, pointer, etc). The functions which are 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 which will assign 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++?

Constructor in C++ is a special member function of a class whose task is to initialize the object of the class, it’s special because it has the same name as that of the class. It is called a constructor because it constructs the value of data members at the time of object initialization. The compiler invokes the constructor whenever an object is created. Since a constructor defines the value to a data member, it has no return type.

Syntax of Constructor:

class scaler {
  public:
    scaler() { //constructor
      // constructor body
    }
};

Characteristics of Constructors in C++

  • A constructor can be made public, private, or protected as per the design of our program. 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. Note: 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 object of the class and can be accessed using class name with scope resolution operator i.e ‘::’).
  • A constructor in C++ cannot be inherited. Although 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 function call. Whenever an object is created of such a class it contains a ‘virtual-pointer’ which points to the base of the corresponding vtable. Whenever there is a virtual function call, the vtable is used to refer to the function address. But when a constructor of a class is executed there is no virtual table created yet in the memory, which means no virtual pointer is defined yet. As a result, a constructor cannot be declared virtual.

Types of Constructors in C++

There are 4 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’.

In the default constructor, every object of the class is initialized with the same set of values.

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

Syntax:

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

Example:

class Employee {
  public:
    int age;
  
    //default constructor
    Employee() {
      //data member is defined with the help of 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 default value, that 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() {
  Employee e1; //object e1 declared
  cout << e1.age;
  return 0;
}

Output:

0

2. Parameterized Constructor

In a default constructor, it is not possible to initialize different objects with different initial values. What if we need to pass arguments to constructors which are needed to initialize an object? In order to solve this issue, there is a different type of constructor called Parameterized Constructor.

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

Example:

#include <iostream>

using namespace std;

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

int main() {
  Employee c1(40); //object c1 declared with argument 40 which gets assigned to age
  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

Copy constructor is a type of constructor which is 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. Whenever there is a need for an object with the same values for data members as of an already existing object, a copy constructor comes into picture. A copy constructor is invoked when an existing object is passed as a parameter.

To know more about copy constructors in C++, refer to this article.

Syntax:

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

Example:

#include<iostream>
using namespace std;

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

  public:
    Employee(int x1, int y1) { //parameterized constructor
      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() {
  Employee employee1(34000, 2); // Parameterized constructor
  Employee employee2 = employee1; // Copy constructor
  cout << "Employee1 using parameterized constructor : \n";
  employee1.display();
  cout << "Employee2 using copy constructor : \n";
  employee2.display();
  return 0;
}

Output:

Employee1 using 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 main() function. The data members salary, 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 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 members salary,experience of object employee2 are assigned to values possessed by salary,experience data members of object employee1(i.e. 34000, 2) respectively.

4. Dynamic Constructor

When 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 dynamic memory allocator new in a constructor, it is known as 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 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 main() function, the parameterized constructor(i.e. Employee(int x) in class definition) is called and memory is assigned dynamically.

What is a Destructor in C++?

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 also gets destroyed with it. 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:
    scaler(); //constructor
    ~scaler(); //destructor
};

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 and it 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 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 code below.
  • A destructor can be written anywhere in the class definition. But to bring an amount of 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) {
  Department d1; //creating an object of Department  
  Employee e2; //creating an object of Employee
  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), it’s 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 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 the 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 important 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. The number and type of class constructors you implement for a class will always depend on the needs of the programmer and class. Hopefully, this article gave you the necessary knowledge to do so.

That’s all for now folks!

Thanks for reading.

Challenge Time!

quiz Time to test your skills and win rewards! Note: Rewards will be credited after the next product update.