Destructors in C++
What is destructor?
Destructor is a member function which destructs or deletes an object.
Destructor is a member function which destructs or deletes an object.
When is destructor called?
A destructor function is called automatically when the object goes out of scope:
(1) the function ends
(2) the program ends
(3) a block containing local variables ends
(4) a delete operator is called
A destructor function is called automatically when the object goes out of scope:
(1) the function ends
(2) the program ends
(3) a block containing local variables ends
(4) a delete operator is called
How destructors are different from a normal member function?
Destructors have same name as the class preceded by a tilde (~).
Destructors don’t take any argument and don’t return anything.
Destructors have same name as the class preceded by a tilde (~).
Destructors don’t take any argument and don’t return anything.
**FULL DESCRIPTION ABOUT DESTRUCTOR:-
A Destructor as the name implies ,is used to destroy the objects have been created by a constructor. Like a constructor, Destructor is a member function whose name is the same
as the class name But it is preceded by tilde(~).
1. A Destructor never takes any argument nor does it return any value.it will be invoked implicity by the compiler upon exit from the program to clean up storage that is no longer accessible.
2. it is a good practise to declare Destructors in a program since it releases memory space for future use.
3. Whenever; new is used to Allocate memory in the constructors. we should use delete to free that memory.
#include<iostream>
using namespace std;
int count=0;
class test
{
public: test()
{
count++;
cout<<"\n constructor msg: object"<<count;
}
~test()
{
cout<<"Destructor msg:"<<count;
count--;
}
};
int main()
{
cout<<"inside main block..";
test T1;
{
cout<<"inside block..";
test T1,T2,T3;
cout<<"\n Leaving block..";
}
cout<<"\n Back inside main block..";
return 0;
}
input/output:-
inside main block..constructor msg: object1inside block..
constructor msg: object2
constructor msg: object3
constructor msg: object4
Leaving block..Destructor msg:4Destructor msg:3Destructor msg:2
Back inside main block..Destructor msg:1
Can there be more than one destructor in a class?
No, there can only one destructor in a class with classname preceded by ~, no parameters and no return type.
No, there can only one destructor in a class with classname preceded by ~, no parameters and no return type.
Can a destructor be virtual?
Yes, In fact, it is always a good idea to make destructors virtual in base class when we have a virtual function. See virtual destructor for more details.
Yes, In fact, it is always a good idea to make destructors virtual in base class when we have a virtual function. See virtual destructor for more details.
You may like to take a quiz on Destructors.
Virtual Destructor
Deleting a derived class object using a pointer to a base class that has a non-virtual destructor results in undefined behavior. To correct this situation, the base class should be defined with a virtual destructor. For example, following program results in undefined behavior.
// CPP program without virtual destructor
// causing undefined behavior
#include<iostream>
using namespace std;
class base {
public:
base()
{ cout<<"Constructing base \n"; }
~base()
{ cout<<"Destructing base \n"; }
};
class derived: public base {
public:
derived()
{ cout<<"Constructing derived \n"; }
~derived()
{ cout<<"Destructing derived \n"; }
};
int main(void)
{
derived *d = new derived();
base *b = d;
delete b;
getchar();
return 0;
}
input/output:-
Constructing base
Constructing derived
Destructing base
Making base class destructor virtual guarantees that the object of derived class is destructed properly, i.e., both base class and derived class destructors are called. For example,
#include<iostream>
using namespace std;
class base {
public:
base()
{ cout<<"Constructing base \n"; }
virtual ~base()
{ cout<<"Destructing base \n"; }
};
class derived: public base {
public:
derived()
{ cout<<"Constructing derived \n"; }
~derived()
{ cout<<"Destructing derived \n"; }
};
int main(void)
{
derived *d = new derived();
base *b = d;
delete b;
getchar();
return 0;
}
input/output:-
Constructing base
Constructing derived
Destructing derived
Destructing base
Pure virtual destructor in C++
Can a destructor be pure virtual in C++?
Yes, it is possible to have pure virtual destructor. Pure virtual destructors are legal in standard C++ and one of the most important things to remember is that if a class contains a pure virtual destructor, it must provide a function body for the pure virtual destructor. You may be wondering why a pure virtual function requires a function body. The reason is because destructors (unlike other functions) are not actually ‘overridden’, rather they are always called in the reverse order of the class derivation. This means that a derived class’ destructor will be invoked first, then base class destructor will be called. If the definition of the pure virtual destructor is not provided, then what function body will be called during object destruction? Therefore the compiler and linker enforce the existence of a function body for pure virtual destructors.
Consider the following program:
Yes, it is possible to have pure virtual destructor. Pure virtual destructors are legal in standard C++ and one of the most important things to remember is that if a class contains a pure virtual destructor, it must provide a function body for the pure virtual destructor. You may be wondering why a pure virtual function requires a function body. The reason is because destructors (unlike other functions) are not actually ‘overridden’, rather they are always called in the reverse order of the class derivation. This means that a derived class’ destructor will be invoked first, then base class destructor will be called. If the definition of the pure virtual destructor is not provided, then what function body will be called during object destruction? Therefore the compiler and linker enforce the existence of a function body for pure virtual destructors.
Consider the following program:
#include <iostream>
class Base
{
public:
virtual ~Base()=0; // Pure virtual destructor
};
class Derived : public Base
{
public:
~Derived()
{
std::cout << "~Derived() is executed";
}
};
int main()
{
Base *b=new Derived();
delete b;
return 0;
}
input/output:-
The linker will produce error in the above program.
Now if the definition for the pure virtual destructor is provided, then the program compiles & runs fine.
#include <iostream>
class Base
{
public:
virtual ~Base()=0; // Pure virtual destructor
};
Base::~Base()
{
std::cout << "Pure virtual destructor is called";
}
class Derived : public Base
{
public:
~Derived()
{
std::cout << "~Derived() is executed\n";
}
};
int main()
{
Base *b = new Derived();
delete b;
return 0;
}
input/output:-
~Derived() is executed
Pure virtual destructor is called