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.

No comments: