delete expression
[zh]销毁先前由 new-表达式 分配的对象并释放已获取的内存区域。[/zh]
[zh]内容[/zh] |
[[zh]编辑[/zh]] [zh]语法[/zh]
:: ([zh]可选[/zh]) delete [zh]表达式[/zh] |
(1) | ||||||||
:: ([zh]可选[/zh]) delete[] [zh]表达式[/zh] |
(2) | ||||||||
[zh]表达式[/zh] | - | [zh]以下之一[/zh]
|
[[zh]编辑[/zh]] [zh]解释[/zh]
[zh]给定从[/zh] [zh]表达式[/zh] [zh]求值的指针(在可能的转换之后)作为[/zh] ptr。
- [zh]空指针,[/zh]
- [zh]指向由 new-表达式 创建的非数组对象的指针,或[/zh]
- [zh]指向由 new-表达式 创建的非数组对象的基础子对象的指针。[/zh]
delete-[zh]表达式的结果始终具有[/zh] void [zh]类型。[/zh]
[zh]如果被删除的对象在删除点具有不完整类类型,并且完整类具有非平凡析构函数或释放函数,则行为是未定义的[/zh](C++26[zh] 前[/zh])[zh]程序是非良构的[/zh](C++26[zh] 起[/zh])。
[zh]如果[/zh] ptr [zh]不是空指针,并且释放函数不是销毁型 delete[/zh](C++20[zh] 起[/zh])[zh],delete-表达式调用正在销毁的对象的析构函数(如果有),或者对于正在销毁的数组的每个元素(从数组的最后一个元素到第一个元素)。析构函数必须可以从 delete-表达式 出现的位置访问。[/zh]
[zh]之后,无论任何析构函数是否抛出异常,delete-表达式都会调用释放函数:operator delete(第一个版本)或 operator delete[](第二个版本),除非匹配的 new-表达式与另一个 new-表达式 组合[/zh](C++14[zh] 起[/zh])。
[zh]释放函数的名称在[/zh] ptr [zh]指向的对象的动态类型的范围内查找,这意味着如果存在类特定的释放函数,则在全局函数之前找到它们。如果在 delete-表达式 中存在 ::
,则此查找仅检查全局命名空间。在任何情况下,都会丢弃通常释放函数以外的任何声明。[/zh]
[zh]如果找到任何释放函数,则按如下方式选择要调用的函数(有关这些函数及其效果的更详细描述,请参见释放函数)[/zh]
|
(C++20[zh] 起[/zh]) |
|
(C++17[zh] 起[/zh]) |
- [zh]如果找到的释放函数是类特定的,则大小未知类特定的释放函数(不带 std::size_t 类型的参数)优先于大小感知类特定的释放函数(带有 std::size_t 类型的参数)。[/zh]
|
(C++14[zh] 起[/zh]) |
[zh]选择的释放函数必须可以从 delete-表达式 出现的位置访问,除非在动态类型的虚析构函数的定义点选择了释放函数。[/zh]
[zh]要回收的存储块的指针作为第一个参数传递给上述过程选择的释放函数。块的大小作为可选的 std::size_t 参数传递。对齐要求作为可选的 std::align_val_t 参数传递。[/zh](C++17[zh] 起[/zh])
[zh]如果[/zh] ptr [zh]是空指针值,则不会调用析构函数,并且可能调用或不调用释放函数(未指定),但默认释放函数保证在传递空指针时什么也不做。[/zh]
[zh]如果[/zh] ptr [zh]是指向用 new 分配的对象的基类子对象的指针,则基类的析构函数必须是虚函数,否则行为是未定义的。[/zh]
[[zh]编辑[/zh]] [zh]注解[/zh]
[zh]无法删除指向 void 的指针,因为它不是指向对象类型的指针。[/zh]
[zh]由于关键字 delete 后面的方括号对始终被解释为 delete-表达式 的数组形式,因此在 delete 之后立即带有空捕获列表的 lambda-表达式 必须用括号括起来。[/zh] // delete []{ return new int; }(); // parse error delete ([]{ return new int; })(); // OK |
(C++11[zh] 起[/zh]) |
[[zh]编辑[/zh]] [zh]关键字[/zh]
[[zh]编辑[/zh]] [zh]缺陷报告[/zh]
[zh]以下行为变更缺陷报告已追溯应用于先前发布的 C++ 标准。[/zh]
DR | [zh]应用于[/zh] | [zh]已发布行为[/zh] | [zh]正确行为[/zh] |
---|---|---|---|
CWG 288 | C++98 | [zh]对于第一种形式,静态类型[/zh] [zh]操作数与其动态类型进行比较[/zh] |
[zh]比较要删除的对象的静态类型[/zh] [zh]与其动态类型[/zh] |
CWG 353 | C++98 | [zh]如果析构函数抛出异常,是否会调用释放函数,这是未指定的[/zh] [zh]析构函数抛出异常时是否会调用释放函数,这是未指定的[/zh] |
[zh]始终调用[/zh] |
CWG 599 | C++98 | [zh]第一种形式可以接受空指针[/zh] [zh]任何类型,包括函数指针[/zh] |
[zh]对象类型指针除外,[/zh] [zh]所有其他指针类型都被拒绝[/zh] |
CWG 1642 | C++98 | [zh]表达式[/zh] [zh]可以是指针左值[/zh] | [zh]不允许[/zh] |
CWG 2474 | C++98 | [zh]删除指向相似但不同类型的对象的指针会导致未定义的行为[/zh] [zh]删除指向相似但不同类型的对象的指针会导致未定义的行为[/zh] |
[zh]变得良好定义[/zh] |
CWG 2624 | C++98 | [zh]从非分配获得的指针[/zh] operator new[] [zh]可以传递给[/zh] delete[] |
[zh]禁止[/zh] |
CWG 2758 | C++98 | [zh]不清楚如何对释放函数和析构函数进行访问控制[/zh] [zh]不清楚如何对释放函数和析构函数进行访问控制[/zh] |
[zh]变得清晰[/zh] |