在基类中重载操作符删除 [英] Overloading operator delete in a base class

查看:144
本文介绍了在基类中重载操作符删除的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

从C ++标准(ISO / IEC 14882:2003(E)),§12.5.4,关于重载 operator delete

From the C++ standard (ISO/IEC 14882:2003(E)), §12.5.4, about overloading operator delete:


如果delete-expression以unary :: operator开头,则在全局范围中查找释放函数的名称。否则,如果delete-expression用于释放静态类型具有虚拟析构函数的类对象,则释放函数是由动态类型的虚拟析构函数(12.4)的定义中的lookup所找到的。否则,如果delete-expression用于释放
类T或其数组的对象,则对象的静态和动态类型应该是相同的,并且在T的范围中查找重新分配函数的名称。此查找无法找到名称,名称在全局范围中查找。如果查找结果不明确或不可访问,或者查找选择了一个布置解除分配函数,程序就会失败。

If a delete-expression begins with a unary :: operator, the deallocation function's name is looked up in global scope. Otherwise, if the delete-expression is used to deallocate a class object whose static type has a virtual destructor, the deallocation function is the one found by the lookup in the definition of the dynamic type's virtual destructor (12.4). Otherwise, if the delete-expression is used to deallocate an object of class T or array thereof, the static and dynamic types of the object shall be identical and the deallocation function's name is looked up in the scope of T. If this lookup fails to find the name, the name is looked up in the global scope. If the result of the lookup is ambiguous or inaccessible, or if the lookup selects a placement deallocation function, the program is ill-formed.

§12.5.7也很有意思:

§12.5.7 is also interesting:


由于成员分配和释放功能是静态的,因此它们不能是虚拟的。 [注意:然而,当delete-expression的cast-expression引用类类型的对象时,因为实际调用的释放函数在作为对象的动态类型的类的范围中查找,如果析构函数是虚拟的,效果是一样的。例如,

Since member allocation and deallocation functions are static they cannot be virtual. [Note: however, when the cast-expression of a delete-expression refers to an object of class type, because the deallocation function actually called is looked up in the scope of the class that is the dynamic type of the object, if the destructor is virtual, the effect is the same. For example,



struct B {
    virtual ˜B();
    void operator delete(void*, size_t);
};
struct D : B {
    void operator delete(void*);
};
void f()
{
    B* bp = new D;
    delete bp; // uses D::operator delete(void*)
}




这里,D类的非数组对象的存储由D :: operator delete()释放,因为虚拟析构函数。]

Here, storage for the non-array object of class D is deallocated by D::operator delete(), due to the virtual destructor.]

阅读完之后,我想知道...

After reading this, I am wondering...


  • 这是标准的这部分完全支持所有主要的C ++编译器(MSVC ++,GCC)?

  • 如果是这样,他们是怎么做的?隐藏虚拟函数? 特殊虚拟析构函数调用? RTTI?

  • 使用标准中的示例:如果在单独的EXE / DLL / DSO中定义f()和D :: operator delete() (假设一切都使用相同的编译器编译,当然)

§5.3.5.5也可能是相关的:

§5.3.5.5 may also be relevant:


在第一个选择(删除对象)中,如果操作数的静态类型与其动态类型不同,则静态类型应为基类操作数的动态类型和静态类型应具有虚拟析构函数或行为未定义。在第二个选择(删除数组)中,如果要删除的对象的动态类型与其静态类型不同,则该行为是未定义的。

In the first alternative (delete object), if the static type of the operand is different from its dynamic type, the static type shall be a base class of the operand's dynamic type and the static type shall have a virtual destructor or the behavior is undefined. In the second alternative (delete array) if the dynamic type of the object to be deleted differs from its static type, the behavior is undefined.


推荐答案

我不太了解VC ++ ABI,但是安腾ABI有很好的文档。

I don't know much about VC++ ABI, but the Itanium ABI is well documented.

href =http://www.codesourcery.com/public/cxx-abi/abi.html#mangling>名称管理计划,请参阅:

Looking up at the name mangling scheme, one see:

<ctor-dtor-name> ::= C1     # complete object constructor
                 ::= C2     # base object constructor
                 ::= C3     # complete object allocating constructor
                 ::= D0     # deleting destructor
                 ::= D1     # complete object destructor
                 ::= D2     # base object destructor

D0#deleting destructor ,这意味着即使 delete 是非虚拟的,它可以被认为是虚拟的所有效果和目的。

Of interest: D0 # deleting destructor, which means that even though delete is non virtual, since it is called from the virtual destructor, it can be considered virtual for all effects and purposes.

这篇关于在基类中重载操作符删除的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆