delete 表达式

来自cppreference.com
< cpp‎ | language
 
 
 
表达式
概述
值类别(左值 lvalue 、右值 rvalue 、亡值 xvalue )
求值顺序(序列点)
常量表达式
不求值表达式
初等表达式
lambda 表达式(C++11)
字面量
整数字面量
浮点字面量
布尔字面量
字符字面量,包含转义序列
字符串字面量
空指针字面量(C++11)
用户定义字面量(C++11)
运算符
赋值运算符a=b, a+=b, a-=b, a*=b, a/=b, a%=b, a&=b, a|=b, a^=b, a<<=b, a>>=b
自增与自减++a, --a, a++, a--
算术运算符+a, -a, a+b, a-b, a*b, a/b, a%b, ~a, a&b, a|b, a^b, a<<b, a>>b
逻辑运算符a||b, a&&b, !a
比较运算符a==b, a!=b, a<b, a>b, a<=b, a>=b, a<=>b(C++20)
成员访问运算符a[b], *a, &a, a->b, a.b, a->*b, a.*b
其他运算符a(...), a,b, a?b:c
运算符的替代表示
优先级和结合性
折叠表达式(C++17)
new 表达式
delete 表达式
throw 表达式
alignof
sizeof
sizeof...(C++11)
typeid
noexcept(C++11)
运算符重载
类型转换
隐式转换
const_cast
static_cast
reinterpret_cast
dynamic_cast
显式转换 (T)a, T(a)
用户定义转换
 

析构先前由 new 表达式分配的对象,并释放获得的内存区域

目录

[编辑] 语法

::(可选)    delete    expression (1)
::(可选)    delete [] expression (2)
1) 销毁 new 表达式创建的单个非数组对象
2) 销毁 new[] 表达式创建的数组

[编辑] 解释

对于第一(非数组)形式, expression 必须是指向对象类型的指针或按语境隐式转换到这种指针的类类型,且其值必须是或指向 new 表达式所创建的非数组对象的指针,或指向 new 表达式所创建的对象的基类子对象的指针。若 expression 是其他值,包含若它是通过new 表达式的数组形式获得的指针,则行为未定义

对于第二(数组)形式, expression 必须是空指针值或先前由 new 表达式获得的指针值。若 expression 是其他东西,包含若它是由 new 表达式的非数组形式获得的指针,则行为未定义

表达式的结果始终拥有 void 类型。

若被删除的对象在删除点拥有不完整类类型,且完整类类型拥有非平凡析构函数或解分配函数,则行为未定义。

expression 不是空指针,则 delete 表达式对被销毁的对象,或对要被销毁的数组的每个元素(从数组的最后元素回退到首元素)调用要被销毁的对象的析构函数(若它存在)。

之后,除非匹配的 new 表达式与另一 new 表达式结合, (C++14 起) delete 表达式调用解分配函数,它是 operator delete (对于表达式的第一版本)或 operator delete[] (对表达式的第二版本)。

解分配函数的名称在 expression 所指向对象的动态类型的作用域查找,这表示类指定解分配函数若存在,则在全局者之前找到。若 delete 表达式中存在 :: ,则此查找只检验全局命名空间。

若查找找到多于一个解分配函数,则调用的函数按下列方式选择(这些函数及其效应的更详细描述见解分配函数):

  • 若类型的对齐要求超出 __STDCPP_DEFAULT_NEW_ALIGNMENT__ ,则偏好具对齐解分配函数(带 std::align_val_t 类型参数)。对于其他类型,偏好无对齐解分配函数(不带 std::align_val_t 类型参数)。
  • 若正好只找到一个偏好函数,则选择该函数。
  • 若找到多于一个偏好函数,则下一步中只考虑偏好函数。
  • 若找不到偏好函数,则下一步中考虑非偏好函数。
(C++17 起)
  • 若找到的解分配函数是类指定的,则偏好不具大小的类指定解分配函数(无 std::size_t 类型参数)甚于具大小的类指定解分配函数(带 std::size_t 类型参数)
  • 否则,查找抵达全局作用域,且:
  • 若类型完整,且若只对于 delete[] 的运算数是指向拥有非平凡析构函数或一个(可以多维)数组的指针,则因此选择具大小的全局函数(带 std::size_t 类型参数)
  • 否则,选择具全局具大小分配函数(带 std::size_t 类型参数)还是全局不具大小解分配函数(无 std::size_t 类型参数)是未指定的
(C++14 起)

指向要被回收的存储块的指针会作为首参数,传递给按上述方式选择的解分配函数。块大小作为可选的 std::size_t 参数传递。对齐要求作为可选的 std::align_val_t 参数传递。 (C++17 起)

expression 求值为空指针值,则不调用析构函数,且可能也可能不调用解分配函数(这是实现定义的),但默认解分配函数保证在处理空指针时不做任何事。

(C++14 前)

expression 求值为空指针值,则不调用析构函数,且不调用解分配函数。

(C++14 起)

expression 求值为以 new 分配的指向对象的基类子对象的指针,则基类的析构函数必须为虚,否则行为未定义。

[编辑] 注意

指向 void 的指针不能删除,因为它不是指向完整对象类型的指针。

因为后随关键词 delete 的一对方括号始终转译为 delete 的数组形式,故立即在 delete 后的拥有空捕获列表的 lambda 表达式必须用括号环绕。

// delete []{return new int; }(); // 剖析错误
delete ([]{return new int; })(); // OK
(C++11 起)

[编辑] 关键词

delete