fal*_*tro 14 c++ operator-overloading
我发现这个问题同样问题,但是只有"新"部分得到了回答,所以这里再说一次.
为什么delete运算符必须是静态的?不知何故,它没有意义.新运算符非常有意义,就像构造函数不能虚拟一样,新运算符也不行.但是,析构函数可以(并且应该)在使用继承时是虚拟的,以便允许销毁正在使用的对象(通过多态)作为基类.
据我所知,当调用delete运算符时,该对象已被销毁,因此不存在"this".然而,使用与虚拟析构函数相同的推理仍然有意义的是让delete运算符与创建对象的new运算符匹配.
这就是我的意思
class A
{
public:
virtual ~A() {}
};
class B : public A
{
public:
void* operator new (size_t sz);
void operator delete (void* ptr, size_t sz);
};
Run Code Online (Sandbox Code Playgroud)
现在如果我们这样做
A *ptr = new B();
delete ptr; // <-- fail
Run Code Online (Sandbox Code Playgroud)
应该调用一个删除操作符(默认值),因为它是静态的,并且在编译时不知道(除了这里的小事),delete-operator是正确的.
但是,我用上面的代码做了一个小的测试程序(在new/delete操作符中只有malloc/free,在delete中只有print语句),并使用g ++编译它.非常意外地运行它会在B的删除操作符中产生输出.
我的(真正的)问题是:删除操作符是否有一些隐含的"虚拟"?在没有这个指针的意义上它只是静态的吗?或者这只是一个g ++功能?
我开始查看C++规范,但我必须承认,我有点不知所措,所以任何帮助都会受到赞赏.
CB *_*ley 17
语言规则中的答案实际上是12.5 [class.free].
如果要通过指向基类的指针进行删除,则析构函数必须是虚拟的,否则会得到未定义的行为.否则,实现必须确定要删除的对象的动态类型.
12.5/4表示当delete没有前缀时,通过在动态类型的虚拟析构函数的上下文中::查找来确定释放函数delete.这确保了类似虚拟的查找,即使operator delete它始终是static成员函数.
原始分配和释放在概念上发生在对象的生命周期之外,因此在调用释放函数时,不再有对象提供虚拟查找机制,但查找规则确保operator delete具有动态(virtual-lite!)查找机制.这意味着操作员删除可以明显地static与原始对象的动态类型失去联系.