假设没有Buffer::operator delete
,delete buf;
版本是正确的,并且会进行所有适当的清理。为了更安全一点,你可以说::delete buf;
.
语言律师辩论材料如下。
5.3.5/1
delete-expression运算符销毁由new-expression创建的最派生对象 (1.8) 或数组。
删除表达式:
::
选择 delete
强制转换表达式
::
选择 delete [ ]
强制转换表达式
第一种选择用于非数组对象,第二种选择用于数组。...
5.3.5/2
...在第一种选择(delete object)中,操作数的值可以是空指针,指向由先前的new-expressiondelete
创建的非数组对象的指针,或指向表示的子对象(1.8)的指针这种对象的基类(第 10 条)。如果不是,则行为未定义。
因此,指针必须指向由new-expression创建的对象,该对象定义为:
5.3.4/1
新表达式:
::
opt new
new-placement opt new-type-id new-initializer opt
::
opt new
new-placement opt (
type-id )
new-initializer opt
新安置:
因此,“新位置”确实算作new-expression。没有什么禁止删除表达式的。
此外,尽管有自定义创建,但事实证明delete-expression确实正确地清理了对象。
5.3.5/6-9
如果delete-expression的操作数的值不是空指针值,则delete-expression将为要删除的对象或数组的元素调用析构函数(如果有)。...
如果delete-expression的操作数的值不是空指针值,则delete-expression将调用释放函数(3.7.4.2)。否则,未指定是否将调用释放函数。[注意:无论对象的析构函数或数组的某些元素是否抛出异常,都会调用释放函数。-结束注]
当删除表达式中的关键字前面delete
带有一元运算符时,全局释放函数用于释放存储空间。::
所以::delete buf;
完全等价于:
try {
buf->~Buffer();
} catch(...) {
::operator delete(mem);
throw;
}
::operator delete(mem);