C++ Constructors and Destructors test – General Questions
C++ Constructors are special class functions which performs initialization of every object. Destructors are used to destroy Objects of a class in C++.
What is constructors in C++ Programming ?
C++ Constructors
In this tutorial, we will learn about the C++ constructors and its type (default, parameterized, and copy-constructor) with the help examples.
Constructor
A Constructor is a special member method which will be called implicitly (automatically) whenever an object of class is created.
Constructors are special class functions which performs initialization of every object. The Compiler calls the Constructor whenever an object is created.
Constructors initialize values to object members after storage is allocated to the object.
How C++ constructors are different from a normal member function?
A constructor is different from normal functions in following ways:
- Constructor has same name as the class itself.
- Constructors don’t have return type.
- A constructor is automatically called when an object is created.
- If we do not specify a constructor, C++ compiler generates a default constructor for us (expects no parameters and has an empty body).
For example,
class A {
public:
// constructor
A() {
// object initialization
}
};
Here, the function A()
is a constructor of the class A
. Notice that the constructor
- has the same name as the class,
- does not have a return type, and
- is
public
Types of C++ Constructors
Constructors are of three types:
1. Default Constructor
2. Parameterized Constructor
3. Copy Constructor
C++ Default Constructor
Default constructor is the constructor which doesn’t take any argument. It has no parameter. It is invoked at the time of creating object.
For example:-
Example 1: C++ program to demonstrate the use of Default Constructor
#include <iostream>
using namespace std;
// declare a class
class Cube {
private:
int side;
public:
// create a constructor
Cube() {
// initialize private variables
side = 6;
cout << "How many sides in a 3/3 cube." << endl;
cout << "Cude has" << side << "Sides." endl;
}
};
int main() {
// create an object
Cube cude1;
return 0;
}
Output
How many sides in a 3/3 cube. Cube has 6 Sides.
Here, when the cube1 object is created, the Cube()
constructor is called. This sets the side variable of the object to 6
.
Note: If we have not defined a constructor in our class, then the C++ compiler will automatically create a default constructor with an empty code and no parameters.
In this case, as soon as the object is created the constructor is called which initializes its data members.
A default constructor is so important for initialization of object members, that even if we do not define a constructor explicitly, the compiler will provide a default constructor implicitly.
C++ Parameterized Constructor
In C++, a constructor with parameters is known as a parameterized constructor. These are the constructors with parameter.
Using this Constructor you can provide different values to data members of different objects, by passing the appropriate values as argument. This is the preferred method to initialize member data.
For Example:-
Example 2: C++ program to calculate the area of a Rectangle
To print the content of a void pointer, we use the static_cast
operator. It converts the pointer from void*
type to the respective data type of the address the pointer is storing:
// C++ program to understand Parameterized Constructor
#include <iostream>
using namespace std;
// declare a class
class Rect {
private:
double length;
double height;
public:
// create parameterized constructor
Rect(double len, double hgt) {
// initialize private variables
length = len;
height = hgt;
}
double calculateArea() {
return length * height;
}
};
int main() {
// create object and initialize data members
Rect rect1(5.0, 10.5);
Rect rect2(6.0, 8.4);
cout << "The Area of Rectangle 1: " << rect1.calculateArea() << endl;
cout << "The Area of Rectangle 2: " << rect2.calculateArea() << endl;
return 0;
}
Output
The Area of Rectangle 1: 52.5 The Area of Rectangle 2: 50.4
Here, we have created a parameterized constructor Rect()
that has 2 parameters: double len
and double hgt
. The values contained in these parameters are used to initialize the member variables length and height.
When we create an object of the Cube
class, we pass the values for the member variables as arguments. The code for this is:
Side side1(5.0, 10.5);
Side side2(6.0, 8.4);
With the member variables thus initialized, we can now calculate the area of the side with the calculateArea()
function.
Uses of Parameterized Constructor:
- It is used to initialize the various data elements of different objects with different values when they are created.
- It is used to overload constructors.
C++ Copy Constructor
A copy constructor is a member function which initializes an object using another object of the same class. These are special type of Constructors which takes an object as argument, and is used to copy values of data members of one object into other object.
For Example:-
Example 3: C++ Program to understand Copy Constructor
#include <iostream>
using namespace std;
// declare a class
class Rect {
private:
double length;
double height;
public:
// parameterized constructor
Rect(double len, double hgt) {
// initialize private variables
length = len;
height = hgt;
}
// copy constructor with a Rect object as parameter
Rect(Rect &obj) {
// initialize private variables
length = obj.length;
height = obj.height;
}
double calculateArea() {
return length * height;
}
};
int main() {
// create an object of Rect class
Rect rect1(5.0, 10.5);
// print area of rect1
cout << "The Area of Rectangle 1: " << rect1.calculateArea() << endl;
// copy contents of room1 to another object rect2
Rect rect2 = rect1;
// print area of rect2
cout << "The Area of Rectangle 2: " << rect2.calculateArea() << endl;
return 0;
}
Output
The Area of Rectangle 1: 52.5 The Area of Rectangle 2: 52.5
In this program, we have used a copy constructor to copy the contents of one object of the Rect
class to another. The code of the copy constructor is:
Rect(Rect &obj) {
length = obj.length;
height = obj.height;
}
Notice that the parameter of this constructor has the address of an object of the Rect
class.
We then assign the values of the variables of the first object to the corresponding variables of the second object. This is how the contents of the object is copied.
In main()
, we then create two objects rect1 and rect2 and then copy the contents of the first object to the second with the code
Rect rect2 = rect1;
Note: A constructor is primarily used to initialize objects. They are also used to run a default code when an object is created.
What is Destructors ?
C++ Destructors
In this tutorial, we will learn about the C++ destructor, Virtual and Pure virtual destructor with the help examples and when does destructor called and its rules.
Destructor
Destructor is a member function which deletes an object. A destructor is called automatically by the compiler when the object goes out of scope. And A destructor is a special member function that works just opposite to constructor, unlike constructors that are used for initializing an object, destructors destroy (or delete) the object.
A destructor works opposite to constructor and defined like constructor; it destructs the objects of classes. It can be defined only once in a class and must have same name as class. Like constructors, it is invoked automatically. But it is prefixed with a tilde sign (~).
Syntax:
~className{
// Some code
};
Note: C++ destructor cannot have parameters. Moreover, modifiers can’t be applied on destructors.
Properties of Destructor
A constructor is different from normal functions in following ways:
- Destructor function is automatically invoked when the objects are destroyed.
- It cannot be declared static or const.
- The destructor does not have arguments.
- It has no return type not even void.
- An object of a class with a Destructor cannot become a member of the union.
- A destructor should be declared in the public section of the class.
- The programmer cannot access the address of destructor.
When does the destructor get called?
A destructor function is called automatically when the object goes out of scope:
(1) When the function ends.
(2) When the program ends.
(3) When a scope (the { } parenthesis) containing local variable ends.
(4) When a delete operator is called.
How destructors are different from a normal member function?
A destructor is different from normal functions in following ways:
- Destructors have same name as the class but is preceded by a tilde (~).
- Destructors have no argument and no return value.
Example 1: C++ program to demonstrate the use of Destructor
#include <iostream>
using namespace std;
// declare a class
class hello {
public:
// Constructor
hello() {
cout << "Constructor is Called." << endl;
}
// Destructor
~hello() {
cout << "Destructor is Called." << endl;
}
// Member Function
int display(){
cout << "Hello, Programmer." << endl;
}
};
int main() {
// create an object
hello obj1;
// Member function called
obj.display();
return 0;
}
Output
Constructor is Called. Hello, Programmer. Destructor is Called.
Virtual Destructors in C++
Deleting a derived class object using a pointer of base class type that has a non-virtual destructor results in undefined behavior. To correct this situation, the base class should be defined with a virtual destructor.
Destructors in the Base class can be Virtual. Whenever Upcasting is done, Destructors of the Base class must be made virtual for proper destrucstion of the object when the program exits.
NOTE: Constructors never be Virtual, only Destructors can be Virtual.
For Example:-
Example 2: C++ program for Upcasting without virtual destroctor
To print the content of a void pointer, we use the static_cast
operator. It converts the pointer from void*
type to the respective data type of the address the pointer is storing:
#include <iostream>
using namespace std;
// declare a class
class base {
public:
// Destructor
~base() {
cout << "Destructor base." << endl;
}
};
class derived : publicbase {
public:
// Destructor
~derived() {
cout << "Destructor derived." << endl;
}
}
int main() {
base* b = new derived; // Upcasting
delete b;
return 0;
}
Output
Destructor base.
In the above example, delete b
will only call the Base class destructor, which is undesirable because, then the object of Derived class remains undestructed, because its destructor is never called. Which results in memory leak.
Example 3: C++ program for Upcasting with virtual destroctor
#include <iostream>
using namespace std;
// declare a class
class base {
public:
virtual ~base() {
cout << "Destructor base." << endl;
}
};
class derived : publicbase {
public:
~derived() {
cout << "Destructor derived." << endl;
}
}
int main() {
base* b = new derived; // Upcasting
delete b;
return 0;
}
Output
Destructor base. Destructor derived.
When we have Virtual destructor inside the base class, then first Derived class’s destructor is called and then Base class’s destructor is called, which is the desired behaviour.
Pure Virtual Destructor
When a destructor is initialized with value 0. It is called virtual destructor, it is declared in base class. Like virtual destructor, pure virtual destructor is also possible. But it should be defined in base class.
- The only difference between Virtual and Pure Virtual Destructor is, that pure virtual destructor will make its Base class Abstract, hence you cannot create object of that class.
- There is no requirement of implementing pure virtual destructors in the derived classes.
Example 4: C++ program to understand Pure virtual destroctor
#include <iostream>
using namespace std;
// declare a class
class base {
public:
virtual ~base() = 0; // Pure Virtual Destructor
};
// Definition of Pure Virtual Destructor
base :: ~base() {
cout << "Pure virtual destructor is called.\n";
}
class derived : publicbase {
public:
~derived() {
cout << "Derived Destructor is called." << endl;
}
}
int main() {
base* b = new derived;
delete b;
return 0;
}
Output
Pure virtual destructor is called. Derived Destructor is called.
Rules for defining a Destructor
1) Name should begin with tilde sign(~) and must match class name.
2) There cannot be more than one destructor in a class.
3) Unlike constructors that can have parameters, destructors do not allow any parameter.
4) They do not have any return type, just like constructors.
5) When you do not specify any destructor in a class, compiler generates a default destructor and inserts it into your code.
Important Question / Answers
1. Is there be more than one destructor in a class?
Ans 🙂 No, there can only one destructor in a class with className preceded by ’tilde sign’ ~
, no parameters and no return type.
2. When do we need to write a user-defined destructor?
Ans 🙂 If we do not write our own destructor in class, compiler creates a default destructor for us. The default destructor works fine unless we have dynamically allocated memory or pointer in class. When a class contains a pointer to memory allocated in class, we should write a destructor to release memory before the class instance is destroyed. This must be done to avoid memory leak.