跳到主要内容

std::default_delete

定义于头文件 <memory>

自 C++11 起
template< class T > struct default_delete;
template< class T > struct default_delete<T[]>;

std::default_delete 是 std::unique_ptr 在未指定删除器时使用的默认销毁策略。在典型的实现中,default_delete 的特化是空类,并用于 空基类优化


未特化的 default_delete 使用 delete 来释放单个对象的内存。2)
还提供了用于数组类型的 delete[] 的部分特化。

成员函数

pub(构造函数)构造一个 default_delete 对象
(公共成员函数)
puboperator()删除对象或数组
(公共成员函数)

std::default_delete::default_delete

自 C++11 起
// 1)
constexpr default_delete() noexcept = default;

// 2)
template <class U>
default_delete( const default_delete<U>& d ) noexcept; // (since C++11, until C++23)

template <class U>
constexpr default_delete( const default_delete<U>& d ) noexcept; // (since C++23)

// 3)
template<class U>
default_delete( const default_delete<U[]>& d ) noexcept; // (since C++11, until C++23)

template<class U>
constexpr default_delete( const default_delete<U[]>& d ) noexcept; // (since C++23)

构造一个 std::default_delete 对象。

2)  (仅主 default_delete 模板的成员)
从另一个 std::default_delete 对象构造一个 std::default_delete<T> 对象。此构造函数仅在 U* 可以隐式转换为 T* 时参与重载解析。

3)  (default_delete<T[]> 特化的成员)
从另一个 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()

自 C++11 起
// 1)
void operator()(T* ptr) const; // (since C++11, until C++23)

constexpr void operator()(T* ptr) const; // (since C++23)

// 2)
template <class U>
void operator()(U* ptr) const; // (since C++11, until C++23)

template <class U>
constexpr void operator()(U* ptr) const; // (since C++23)
  1. (仅主 default_delete 模板的成员)
    对 ptr 调用 delete

  2. (default_delete<T[]> 特化的成员)
    对 ptr 调用 delete[]。此函数仅在 U(*)[] 可以隐式转换为 T(*)[] 时参与重载解析。无论如何,如果 U 是不完整类型,程序将格式错误。

参数

ptr - 要删除的对象或数组

异常

无异常保证。


在不完整类型上调用

在代码调用 operator() 的点,类型必须是完整的。在某些实现中,使用 static_assert 来确保这种情况。此要求的理由是,在 C++ 中,在不完整类型上调用 delete 是未定义行为,如果完整类类型具有非平凡的析构函数或去分配函数,因为编译器无法知道是否存在此类函数并且必须调用它们。

注释

特性测试宏标准注释
__cpp_lib_constexpr_memory202202L(C++23)constexpr 构造函数和 operator()

示例

#include <memory>
#include <vector>
#include <algorithm>

int main()
{
// {
// std::shared_ptr<int> shared_bad(new int[10]);
// } // the destructor calls delete, undefined behavior

{
std::shared_ptr<int> shared_good(new int[10], std::default_delete<int[]>());
} // the destructor calls delete[], ok

{
std::unique_ptr<int> ptr(new int(5));
} // unique_ptr<int> uses default_delete<int>

{
std::unique_ptr<int[]> ptr(new int[10]);
} // unique_ptr<int[]> uses default_delete<int[]>

// default_delete can be used anywhere a delete functor is needed
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 2118C++11default_delete<T[]> 的成员函数拒绝限定转换接受

std::default_delete

定义于头文件 <memory>

自 C++11 起
template< class T > struct default_delete;
template< class T > struct default_delete<T[]>;

std::default_delete 是 std::unique_ptr 在未指定删除器时使用的默认销毁策略。在典型的实现中,default_delete 的特化是空类,并用于 空基类优化


未特化的 default_delete 使用 delete 来释放单个对象的内存。2)
还提供了用于数组类型的 delete[] 的部分特化。

成员函数

pub(构造函数)构造一个 default_delete 对象
(公共成员函数)
puboperator()删除对象或数组
(公共成员函数)

std::default_delete::default_delete

自 C++11 起
// 1)
constexpr default_delete() noexcept = default;

// 2)
template <class U>
default_delete( const default_delete<U>& d ) noexcept; // (since C++11, until C++23)

template <class U>
constexpr default_delete( const default_delete<U>& d ) noexcept; // (since C++23)

// 3)
template<class U>
default_delete( const default_delete<U[]>& d ) noexcept; // (since C++11, until C++23)

template<class U>
constexpr default_delete( const default_delete<U[]>& d ) noexcept; // (since C++23)

构造一个 std::default_delete 对象。

2)  (仅主 default_delete 模板的成员)
从另一个 std::default_delete 对象构造一个 std::default_delete<T> 对象。此构造函数仅在 U* 可以隐式转换为 T* 时参与重载解析。

3)  (default_delete<T[]> 特化的成员)
从另一个 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()

自 C++11 起
// 1)
void operator()(T* ptr) const; // (since C++11, until C++23)

constexpr void operator()(T* ptr) const; // (since C++23)

// 2)
template <class U>
void operator()(U* ptr) const; // (since C++11, until C++23)

template <class U>
constexpr void operator()(U* ptr) const; // (since C++23)
  1. (仅主 default_delete 模板的成员)
    对 ptr 调用 delete

  2. (default_delete<T[]> 特化的成员)
    对 ptr 调用 delete[]。此函数仅在 U(*)[] 可以隐式转换为 T(*)[] 时参与重载解析。无论如何,如果 U 是不完整类型,程序将格式错误。

参数

ptr - 要删除的对象或数组

异常

无异常保证。


在不完整类型上调用

在代码调用 operator() 的点,类型必须是完整的。在某些实现中,使用 static_assert 来确保这种情况。此要求的理由是,在 C++ 中,在不完整类型上调用 delete 是未定义行为,如果完整类类型具有非平凡的析构函数或去分配函数,因为编译器无法知道是否存在此类函数并且必须调用它们。

注释

特性测试宏标准注释
__cpp_lib_constexpr_memory202202L(C++23)constexpr 构造函数和 operator()

示例

#include <memory>
#include <vector>
#include <algorithm>

int main()
{
// {
// std::shared_ptr<int> shared_bad(new int[10]);
// } // the destructor calls delete, undefined behavior

{
std::shared_ptr<int> shared_good(new int[10], std::default_delete<int[]>());
} // the destructor calls delete[], ok

{
std::unique_ptr<int> ptr(new int(5));
} // unique_ptr<int> uses default_delete<int>

{
std::unique_ptr<int[]> ptr(new int[10]);
} // unique_ptr<int[]> uses default_delete<int[]>

// default_delete can be used anywhere a delete functor is needed
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 2118C++11default_delete<T[]> 的成员函数拒绝限定转换接受