std::default_delete

来自cppreference.com
< cpp‎ | memory
 
 
工具库
通用工具
格式化库 (C++20)
(C++11)
关系运算符 (C++20 中弃用)
整数比较函数
(C++20)(C++20)(C++20)
(C++20)
swap 与类型运算
(C++14)
(C++11)
(C++11)
(C++11)
(C++17)
常用词汇类型
(C++11)
(C++17)
(C++17)
(C++17)
(C++11)
(C++17)

初等字符串转换
(C++17)
(C++17)
栈踪
 
动态内存管理
智能指针
(C++11)
(C++11)
(C++11)
(C++17 前)
(C++11)
default_delete
(C++11)
(C++23)
分配器
内存资源
未初始化存储
未初始化内存算法
受约束的未初始化内存算法
垃圾收集支持
(C++11)(C++23 前)
(C++11)(C++23 前)
(C++11)(C++23 前)
(C++11)(C++23 前)
(C++11)(C++23 前)
(C++11)(C++23 前)
杂项
(C++20)
(C++11)
(C++11)
C 库
低层内存管理
 
std::default_delete
 
定义于头文件 <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_deletedelete 解分配单个对象的内存。
2) 亦为提供数组类型的使用 delete[] 的部分特化。

成员函数

(构造函数)
构造 default_delete 对象
(公开成员函数)
operator()
删除对象或数组
(公开成员函数)

std::default_delete::default_delete

constexpr default_delete() noexcept = default;
(1)
template <class U>
default_delete( const default_delete<U>& d ) noexcept;
(2) (仅为初等 default_delete 模板的成员)
template<class U>
default_delete( const default_delete<U[]>& d ) noexcept;
(3) (仅为 default_delete<T[]> 模板特化的成员)
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()

void operator()(T* ptr) const;
(1) (仅为初等 default_delete 模板的成员)
template <class U>
void operator()(U* ptr) const;
(2) (仅为 default_delete<T[]> 模板特化的成员)
1)ptr 上调用 delete
2)ptr 上调用 delete[] 。此函数仅若 U(*)[] 能隐式转换为 T(*)[] 才参与重载决议。

任何情况下,若 U 是不完整类型,则程序为谬构。

参数

ptr - 要删除的对象或数组

异常

无异常保证。

在不完整类型上调用

于代码中调用 operator() 点,类型必须完整。一些实现中用 static_assert 确保如此。此要求的原因,是 C++ 中若完整类类型拥有非平凡析构函数或解分配函数,则在不完整类型上调用 delete 是未定义行为,因为编译器无法得知这种函数是否存在且必须被调用。

示例

#include <memory>
#include <vector>
#include <algorithm>
 
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[]>
());
    } // 析构函数调用 delete[] , ok
 
    {
        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++ 标准。

DR 应用于 出版时的行为 正确行为
LWG 2118 C++11 default_delete<T[]> 的成员函数拒绝限定转换 接受

参阅

拥有独有对象所有权语义的智能指针
(类模板)