There are some questions regarding virtual destructor that I am asked very frequently. Answers to all these questions are similar so I am making a common note on it.
• What is the use of virtual destructor?
• When to make base class destructor virtual?
• Is there any overhead for virtual destructor?
• Why don’t we make all the destructor virtual?
• Will the delete operator be overridden?
• Will the delete[] operator be overridden?
What is the use of virtual destructor?
The virtual destructor comes into play when the class is a base class. If the derived class object is deleted using a base class pointer the necessary destruction of the derived class would not happen if only base class destructor is called. To simplify, if the base class destructor is not virtual and if we try to delete the derived class object using base class pointer the derived class destructor will not be called. It’s known that the destruction is done from derived to base; hence if the derived class destructor is called it will call the base class destructor and the proper destruction of the object will be happening. Altogether by making the base class destructor virtual we are making destructor to be capable of overriding.
When to make base class destructor virtual?
Make the destructor of the class virtual if the class has any virtual function. It should probably save because of 2 reasons.
1. Most of the real world base classes will have at least one virtual function.
2. In the real world problems if there is no virtual function in the base class there is no specific advantage in using base class pointer.
Is there any overhead for virtual destructor?
The per-object-space-cost will be nothing because we only make our destructor private when there is at least one virtual method in the base class. When the first virtual method in the class is made; the per-object-space-cost will be paid off and this makes it costless to make the destructor virtual.
Why don’t we make all the destructor virtual?
If there is no virtual function in the base class and you make the destructor virtual it increases the per-object-space-cost for no added advantage. It is safe not to make the destructor if you class,
1. is not a base class
2. or is not having any virtual function
Will the delete operator be overridden?
Yea, the standards state the delete operator will be overridden and the derived class delete operator will be used for the destruction of derived class.
Will the delete[] operator be overridden?
NO, the standards explicitly states the delete[](deleting array of objects) operator will not be overridden and the operator corresponding to the type of pointer will be used for deleting.
For better understanding on delete and delete[] operator with virtual destruction please read the post Virtual Destructor delete and delete[]
Showing posts with label Virtual destructor delete[] delete(). Show all posts
Showing posts with label Virtual destructor delete[] delete(). Show all posts
Wednesday, April 23, 2008
Friday, July 6, 2007
Virtual destruction, delete() and delete[]
Pre-Information
Q. Why base class destructor must be virtual?
A. A base class destructor must be virtual. The reason is if the derived class object is deleted using a base class pointer, the program will be ill-formed( Base class destructor may only be called ), if base class destructor is not virtual.
Tip:
The above rule will only make the program correct if we are NOT deleting the array of objects( ie delete[] ). If we use it the program may be ill-formed.
Example:
struct Base
{
virtual ~Base(){ cout << "~Base()" << endl; }
void operator delete[](void* pObj, size_t){ cout << "Base::delete[] operator" << endl;
::delete [] pObj; }
void operator delete(void* pObj ){ cout << "Base::delete() operator" << endl;
::delete pObj; }
};
struct Derived : Base
{
~Derived(){ cout << "~Derived()" << endl; }
void operator delete[](void* pObj, size_t){ cout << "Derived::operator delete[]" << endl;
::delete [] pObj; }
void operator delete(void* pObj ) { cout << "Derived::operator delete()" << endl;
::delete pObj; }
};
int main()
{
cout << "Creating one derived class object"< Base* pBase = new Derived;
delete pBase; // Deleting a derived class object with base class pointer
cout << "Creating array of derrived class objects";
Base* BasePointer = new Derived[3];
delete[] BasePointer; // Deleting array of derived class objects with base class pointer
getch();
}
In the above program the delete pBase guarantees the proper deallocation of the memory. But the delete[] BasePointer is not assured to be working. The usage of delete[] BasePointer may make the program ill-formed.
If you run the above program it will output:
Creating one derived class object
~Derived()
~Base()
Derived::operator delete()
Creating array of derrived class objects~Derived()
~Base()
~Derived()
~Base()
~Derived()
~Base()
Base::delete[]
The derived class object is deallocated using base class's deallocation function.
This usage is strictly disallowed by C++98 standards.
Q. Why base class destructor must be virtual?
A. A base class destructor must be virtual. The reason is if the derived class object is deleted using a base class pointer, the program will be ill-formed( Base class destructor may only be called ), if base class destructor is not virtual.
Tip:
The above rule will only make the program correct if we are NOT deleting the array of objects( ie delete[] ). If we use it the program may be ill-formed.
Example:
struct Base
{
virtual ~Base(){ cout << "~Base()" << endl; }
void operator delete[](void* pObj, size_t){ cout << "Base::delete[] operator" << endl;
::delete [] pObj; }
void operator delete(void* pObj ){ cout << "Base::delete() operator" << endl;
::delete pObj; }
};
struct Derived : Base
{
~Derived(){ cout << "~Derived()" << endl; }
void operator delete[](void* pObj, size_t){ cout << "Derived::operator delete[]" << endl;
::delete [] pObj; }
void operator delete(void* pObj ) { cout << "Derived::operator delete()" << endl;
::delete pObj; }
};
int main()
{
cout << "Creating one derived class object"<
delete pBase; // Deleting a derived class object with base class pointer
cout << "Creating array of derrived class objects";
Base* BasePointer = new Derived[3];
delete[] BasePointer; // Deleting array of derived class objects with base class pointer
getch();
}
In the above program the delete pBase guarantees the proper deallocation of the memory. But the delete[] BasePointer is not assured to be working. The usage of delete[] BasePointer may make the program ill-formed.
If you run the above program it will output:
Creating one derived class object
~Derived()
~Base()
Derived::operator delete()
Creating array of derrived class objects~Derived()
~Base()
~Derived()
~Base()
~Derived()
~Base()
Base::delete[]
The derived class object is deallocated using base class's deallocation function.
This usage is strictly disallowed by C++98 standards.
Subscribe to:
Comments (Atom)