[zh]命名空间[/zh]
[zh]变体[/zh]
[zh]操作[/zh]

delete expression

[zh]来自 cppreference.cn[/zh]
< cpp‎ | language
 
 
C++ [zh]语言[/zh]
[zh]通用主题[/zh]
[zh]流程控制[/zh]
[zh]条件执行语句[/zh]
if
[zh]迭代语句(循环)[/zh]
for
range-for (C++11)
[zh]跳转语句[/zh]
[zh]函数[/zh]
[zh]函数声明[/zh]
[zh]Lambda 函数表达式[/zh]
inline [zh]说明符[/zh]
[zh]动态异常规范[/zh] ([zh]直到 C++17 弃用[/zh])
noexcept [zh]说明符[/zh] (C++11)
[zh]异常[/zh]
[zh]命名空间[/zh]
[zh]类型[/zh]
[zh]说明符[/zh]
const/volatile
decltype (C++11)
auto (C++11)
constexpr (C++11)
consteval (C++20)
constinit (C++20)
[zh]存储持续期说明符[/zh]
[zh]初始化[/zh]
[zh]表达式[/zh]
[zh]替代表示[/zh]
[zh]字面量[/zh]
[zh]布尔[/zh] - [zh]整数[/zh] - [zh]浮点[/zh]
[zh]字符[/zh] - [zh]字符串[/zh] - nullptr (C++11)
[zh]用户定义[/zh] (C++11)
[zh]实用工具[/zh]
[zh]属性[/zh] (C++11)
[zh]类型[/zh]
typedef [zh]声明[/zh]
[zh]类型别名声明[/zh] (C++11)
[zh]转型[/zh]
[zh]内存分配[/zh]
delete [zh]表达式[/zh]
[zh]类[/zh]
[zh]类特定的函数属性[/zh]
explicit (C++11)
static

[zh]特殊成员函数[/zh]
[zh]模板[/zh]
[zh]杂项[/zh]
 
 

[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]
1) [zh]销毁由 new-表达式 创建的一个非数组对象。[/zh]
2) [zh]销毁由 new[]-表达式 创建的数组。[/zh]

[[zh]编辑[/zh]] [zh]解释[/zh]

[zh]给定从[/zh] [zh]表达式[/zh] [zh]求值的指针(在可能的转换之后)作为[/zh] ptr

1) ptr [zh]必须是以下之一[/zh]
  • [zh]空指针,[/zh]
  • [zh]指向由 new-表达式 创建的非数组对象的指针,或[/zh]
  • [zh]指向由 new-表达式 创建的非数组对象的基础子对象的指针。[/zh]
ptr [zh]的指向类型必须与对象(或基础子对象)的类型相似。如果[/zh] ptr [zh]是任何其他类型,包括如果是通过 new-表达式 的数组形式获得的指针,则行为是未定义的。[/zh]
2) ptr [zh]必须是空指针或指针,其值先前通过 new-表达式 的数组形式获得,其分配函数不是非分配形式(即重载 (10))。[/zh]
ptr [zh]的指向类型必须与数组对象的元素类型相似。如果[/zh] ptr [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]

  • [zh]如果至少一个释放函数是销毁型 delete,则所有非销毁型 delete 都会被忽略。[/zh]
(C++20[zh] 起[/zh])
  • [zh]如果类型的对齐要求超过 __STDCPP_DEFAULT_NEW_ALIGNMENT__,则首选对齐感知释放函数(带有 std::align_val_t 类型的参数)。对于其他类型,首选不对齐感知释放函数(不带 std::align_val_t 类型的参数)。[/zh]
  • [zh]如果找到多个首选函数,则下一步仅考虑首选函数。[/zh]
  • [zh]如果未找到首选函数,则下一步考虑非首选函数。[/zh]
  • [zh]如果只剩下一个函数,则选择该函数。[/zh]
(C++17[zh] 起[/zh])
  • [zh]如果找到的释放函数是类特定的,则大小未知类特定的释放函数(不带 std::size_t 类型的参数)优先于大小感知类特定的释放函数(带有 std::size_t 类型的参数)。[/zh]
  • [zh]否则,查找达到全局作用域,并且[/zh]
  • [zh]如果类型是完整的,并且仅对于数组形式,操作数是指向具有非平凡析构函数或其(可能是多维)数组的类类型的指针,则选择全局大小感知全局函数(带有 std::size_t 类型的参数)。[/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]

delete

[[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]

[[zh]编辑[/zh]] [zh]参见[/zh]