从重载运算符删除中调用成员函数?

Pau*_*cas 5 c++ memory-management operator-overloading

这篇关于二进制兼容的C++接口的文章包含以下代码:

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
    }
  }
};
Run Code Online (Sandbox Code Playgroud)

对我而言,这似乎是错误的:operator delete()原始内存上工作,目的是释放它.对象的析构函数已被调用,因此调用destroy()对"幻像"对象起作用(如果它完全有效).确实:这就是为什么operator delete()需要a void*而不是a Window*(在这种情况下).

所以,设计有缺陷,对吧?(如果它是正确的,为什么它是正确的?)

asc*_*ler 6

我同意(假设Window::destroy不是静态成员函数):

3.8p1:类型对象的生命周期T结束时:如果T是具有非平凡析构函数的类类型,则析构函数调用开始,或者[...]

3.8p5:[...]在对象的生命周期结束之后,在重用或释放对象占用的存储之前,可以使用任何指向对象所在的存储位置的指针.但只是在有限的方面....如果对象将是或者是非POD类类型,则程序具有未定义的行为,如果:指针用于访问非静态数据成员或调用对象的非静态成员函数,或者[...]

(强调我的)