从重载运算符删除中调用成员函数?
这篇关于 二进制兼容的 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
}
}
};
对我来说,这似乎是错误的:operator delete()
适用于原始内存,其预期目的是释放它。该对象的析构函数已经被调用,因此调用 destroy()
对“幻影”对象起作用(如果它起作用的话)。事实上:这就是为什么 operator delete()
采用 void*
而不是 Window*
(在本例中)。
那么,这个设计是有缺陷的,对吧? (如果它是正确的,为什么它是正确的?)
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?)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
我同意(假设 Window::destroy 不是静态成员函数):
(强调我的)
I agree (assuming
Window::destroy
is not a static member function):(emphasis mine)
是的,该代码(如果标记为 C++)是非常错误的。
正如您所说,运算符 new 和 delete 处理原始内存,而不是对象。
然而,那篇文章涉及特定的编译器和特定的实现问题,因此可能在受限的上下文中代码可以工作...此外,MS 并不因他们对可移植 C++ 的关心程度而闻名(实际上相反),所以 可能这种糟糕的代码(或者在 2002 年)实际上不仅可以工作,而且甚至是一个合理的解决方案。
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.
这是真正令人讨厌的代码,试图提供帮助。
文章指出,在 COM 代码中不应
删除
对象,而应调用obj->destroy()
。因此,为了“有帮助”,作者让operator delete 执行销毁调用。可恶的!更好的方法是只声明一个私有操作符delete,这样用户就无法删除对象,而必须找出正确的方法。
That is really nasty code, trying to be helpful.
The article says that in COM code should not
delete
the object, but callobj->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.