std::default_delete
来自cppreference.com
<tbody>
</tbody>
| 在标头 <memory> 定义
|
||
template< class T > struct default_delete; |
(1) | (C++11 起) |
template< class T > struct default_delete<T[]>; |
(2) | (C++11 起) |
std::default_delete 是不指定删除器时 std::unique_ptr 所用的默认删除策略。 default_delete 的特化在典型实现上为空类,并且用于空基类优化。
1) 非特化的
default_delete 用 delete 解分配单个对象的内存。2) 也为数组类型提供了使用
delete[] 的部分特化。成员函数
构造 default_delete 对象 (公开成员函数) | |
| 删除对象或数组 (公开成员函数) |
std::default_delete::default_delete
<tbody> </tbody> constexpr default_delete() noexcept = default; |
(1) | |
| 主模板特化 |
||
template< class U > default_delete( const default_delete<U>& d ) noexcept; |
(2) | (C++11 起) (C++23 起为 constexpr) |
| 数组特化 |
||
template< class U > default_delete( const default_delete<U[]>& d ) noexcept; |
(3) | (C++11 起) (C++23 起为 constexpr) |
1) 构造
std::default_delete 对象。2) 从另一
std::default_delete 对象构造 std::default_delete 对象。 此重载只有在
U* 可隐式转换到 T* 时才会参与重载决议。3) 从另一
std::default_delete<U[]> 对象构造 std::default_delete<T[]> 对象。 此重载只有在
U(*)[] 可隐式转换到 T(*)[] 时才会参与重载决议。参数
| d | - | 复制来源的删除器 |
注解
std::default_delete 的转换构造函数模板令从 std::unique_ptr<Derived> 到 std::unique_ptr<Base> 的隐式转换可行。
std::default_delete::operator()
<tbody> </tbody>| 主模板特化 |
||
void operator()( T* ptr ) const; |
(1) | (C++11 起) (C++23 起为 constexpr) |
| 数组特化 |
||
template< class U > void operator()( U* ptr ) const; |
(2) | (C++11 起) (C++23 起为 constexpr) |
1) 在
ptr 上调用 delete。2) 在
ptr 上调用 delete[]。 此重载只有在
U(*)[] 可隐式转换到 T(*)[] 时才会参与重载决议。 如果
U 是不完整类型,那么程序非良构。参数
| ptr | - | 要删除的对象或数组 |
异常
无异常保证。
在不完整类型上调用
在代码中调用 operator() 的时候类型必须完整。一些实现中用 static_assert 确保如此。此要求的原因,是 C++ 中如果完整类类型拥有非平凡析构函数或解分配函数,那么在不完整类型上调用 delete 是未定义行为,因为编译器无法得知这种函数是否存在且必须被调用。
注解
| 功能特性测试宏 | 值 | 标准 | 功能特性 |
|---|---|---|---|
__cpp_lib_constexpr_memory |
202202L |
(C++23) | constexpr 构造函数和 operator()
|
示例
运行此代码
#include <algorithm>
#include <memory>
#include <vector>
int main()
{
// {
// std::shared_ptr<int> shared_bad(new int[10]);
// } // 析构函数调用 delete,未定义行为
{
std::shared_ptr<int> shared_good(new int[10], std::default_delete<int[]>());
} // OK:析构函数调用 delete[]
{
std::unique_ptr<int> ptr(new int(5));
} // unique_ptr<int> 使用 default_delete<int>
{
std::unique_ptr<int[]> ptr(new int[10]);
} // unique_ptr<int[]> 使用 default_delete<int[]>
// default_delete 能用于需要进行删除的函数对象的任何场所
std::vector<int*> v;
for (int n = 0; n < 100; ++n)
v.push_back(new int(n));
std::for_each(v.begin(), v.end(), std::default_delete<int>());
}
缺陷报告
下列更改行为的缺陷报告追溯地应用于以前出版的 C++ 标准。
| 缺陷报告 | 应用于 | 出版时的行为 | 正确行为 |
|---|---|---|---|
| LWG 2118 | C++11 | default_delete<T[]> 的成员函数拒绝限定性转换
|
接受 |
参阅
(C++11) |
拥有独有对象所有权语义的智能指针 (类模板) |