class Widget
{
public:
Widget() {
cout<<"~Widget()"<<endl;
}
~Widget() {
cout<<"~Widget()"<<endl;
}
void* operator new(size_t sz) throw(bad_alloc) {
cout<<"operator new"<<endl;
throw bad_alloc();
}
void operator delete(void *v) {
cout<<"operator delete"<<endl;
}
};
int main()
{
Widget* w = 0;
try {
w = new Widget();
}
catch(bad_alloc) {
cout<<"Out of Memory"<<endl;
}
delete w;
getch();
return 1;
}
In this code, delete w
does not call the overloaded delete
operator when the destructor is there. If the destructor is omitted, the overloaded delete
is called. Why is this so?
Output when ~Widget() is written
operator new
Out of Memory
Output when ~Widget() is not written
operator new
Out of Memory
operator delete
The reason is that if you have a destructor, the call to the delete operator is done from within the scalar deleting destructor, which in VC contains the call to both your destructor and the delete operator. The compiler provides code that checks whether you're trying to delete a NULL pointer. Deleting such pointer is legal, of course, but the destructor of such object must not be invoked, as it might contain usage of member variables. For that the call to the scalar deleting destructor is avoided, and as a result the call to the delete operator is avoided as well.
When there is no destructor, the compiler just calls the delete operator directly, without generating the scalar deleting destructor. Therefore, in such cases the delete operator is invoked after all.