Reputation: 7133
This article on Binary-compatible C++ Interfaces contains the code:
class Window {
public:
// ...
virtual void destroy() = 0;
void operator delete(void* p) {
if (p) {
Window* w = static_cast<Window*>(p);
w->destroy(); // VERY BAD IDEA
}
}
};
To me, that seems wrong: operator delete()
works on raw memory with the intended purpose to free it. The object's destructor has already been called, so calling destroy()
works on a "phantom" object (if it works at all). Indeed: that's why operator delete()
takes a void*
and not a Window*
(in this case).
So, the design is flawed, right? (If it is correct, why is it correct?)
Upvotes: 5
Views: 420
Reputation: 92271
That is really nasty code, trying to be helpful.
The article says that in COM code should not delete
the object, but call obj->destroy()
instead. So to be "helpful" the author makes operator delete do the destroy call. Nasty!
Much better would have been to just declare a private operator delete, so the user cannot delete objects and must instead figure out the correct way.
Upvotes: 0
Reputation: 114491
Yes, that code (if labelled C++) is very wrong.
Operator new and delete as you say handle raw memory, not objects.
That article however deals with specific compilers and specific implementation issues so may be that in that restricted context the code works... moreover MS isn't exactly well renowned for how nicely they care about portable C++ (au contraire, indeed) so may be that kind of bad code is (or was in 2002) actually not only working but even a reasonable solution.
Upvotes: 0
Reputation: 72356
I agree (assuming Window::destroy
is not a static member function):
3.8p1: The lifetime of an object of type
T
ends when: ifT
is a class type with a non-trivial destructor, the destructor call starts, or [...]3.8p5: [...] After the lifetime of an object has ended and before the storage which the object occupied is reused or released, any pointer that refers to the storage location where the object [...] was located may be used but only in limited ways. ... If the object will be or was of a non-POD class type, the program has undefined behavior if: the pointer is used to access a non-static data member or call a non-static member function of the object, or [...]
(emphasis mine)
Upvotes: 6