I tried to call ::delete
for a class in the operator delete
of it. But the destructor is not called.
I defined a class MyClass
whose operator delete
has been overloaded. The global operator delete
is also overloaded. The overloaded operator delete
of MyClass
will call the overloaded global operator delete
.
class MyClass
{
public:
MyClass() { printf("Constructing MyClass...\n"); }
virtual ~MyClass() { printf("Destroying MyClass...\n"); }
void* operator new(size_t size)
{
printf("Newing MyClass...\n");
void* p = ::new MyClass();
printf("End of newing MyClass...\n");
return p;
}
void operator delete(void* p)
{
printf("Deleting MyClass...\n");
::delete p; // Why is the destructor not called here?
printf("End of deleting MyClass...\n");
}
};
void* operator new(size_t size)
{
printf("Global newing...\n");
return malloc(size);
}
void operator delete(void* p)
{
printf("Global deleting...\n");
free(p);
}
int main(int argc, char** argv)
{
MyClass* myClass = new MyClass();
delete myClass;
return EXIT_SUCCESS;
}
The output is:
Newing MyClass...
Global newing...
Constructing MyClass...
End of newing MyClass...
Constructing MyClass...
Destroying MyClass...
Deleting MyClass...
Global deleting...
End of deleting MyClass...
Actual:
There is only one call to the destructor before calling the overloaded operator delete
of MyClass
.
Expected:
There are two calls to the destructor. One before calling the overloaded operator delete
of MyClass
. Another before calling the global operator delete
.
MyClass::operator new()
should allocate raw memory, of (at least)size
bytes. It should not attempt to completely construct an instance ofMyClass
. The constructor ofMyClass
is executed afterMyClass::operator new()
. Then, thedelete
expression inmain()
calls the destructor, and releases the memory (without calling the destructor again). The::delete p
expression has no information about the type of objectp
points at, sincep
is avoid *
, so cannot invoke the destructor. – Tolu::delete p;
causes undefined behaviour since the type of*p
is not the same as the type of the object being deleted (nor a base class with virtual destructor) – Wirephotovoid*
as operand is even explicitly ill-formed. [expr.delete]/1: "The operand shall be of pointer to object type or of class type. [...] This implies that an object cannot be deleted using a pointer of type void because void is not an object type.*" @OP I have amended my answer. – Racewayvoid *
is an "object pointer type", but not a "pointer to object type", according to [basic.compound]/3. Clear as mud... – Wirephoto