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?)
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)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With