◐ Shell
clean mode source ↗

std::default_delete - cppreference.com

来自cppreference.com

在标头 <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[] 的部分特化。

成员函数

std::default_delete::default_delete

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(*)[] 时才会参与重载决议。

参数

注解

std::default_delete转换构造函数模板令从 std::unique_ptr<Derived>std::unique_ptr<Base> 的隐式转换可行。

std::default_delete::operator()

主模板特化

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 是不完整类型,那么程序非良构。

参数

异常

无异常保证。

在不完整类型上调用

在代码中调用 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[]> 的成员函数拒绝限定性转换 接受

参阅