unique_ptr 与 shared_ptr 中的删除器类型

Deleter type in unique_ptr vs. shared_ptr

当我发现标准以两种完全不同的方式定义指针可能拥有的删除器时,我觉得很好奇。这是来自 cppreference::unique_ptr and cppreference::shared_ptr 的声明:

template<
    class T,
    class Deleter = std::default_delete<T>
> class unique_ptr;

template< class T > class shared_ptr;

如您所见,unique_ptr "saves" Deleter 对象的类型作为模板参数。这也可以从后面从指针中检索 Deleter 的方式看出:

// unique_ptr has a member function to retrieve the Deleter
template<
    class T,
    class Deleter = std::default_delete<T>
>
Deleter& unique_ptr<T, Deleter>::get_deleter();

// For shared_ptr this is not a member function
template<class Deleter, class T>
Deleter* get_deleter(const std::shared_ptr<T>& p);

有人可以解释这种差异背后的原因吗?我显然赞成 unique_ptr 的概念,为什么这也不适用于 shared_ptr?另外,为什么 get_deleter 在后一种情况下是非成员函数?

在这里您可以找到智能指针的原始提案:http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2003/n1450.html

它非常准确地回答了你的问题:

Since the deleter is not part of the type, changing the allocation strategy does not break source or binary compatibility, and does not require a client recompilation.

这也很有用,因为为 std::shared_ptr 的客户端提供了更多的灵活性,例如 shared_ptr 具有不同删除器的实例可以存储在同一个容器中。

此外,因为 shared_ptr 实现无论如何都需要一个共享内存块(用于存储引用计数),并且因为与原始指针相比已经有一些开销,所以添加类型擦除删除器不是这里有很多大事。

另一方面,

unique_ptr 旨在完全没有开销,每个实例都必须嵌入其删除器,因此使其成为类型的一部分是很自然的事情。