删除器类型在unique_ptr与shared_ptr中

时间:2015-01-02 12:32:53

标签: c++ c++11 shared-ptr unique-ptr

当我发现标准以两种完全不同的方式定义std::unique_ptrstd::shared_ptr关于指针可能拥有的Deleter时,我觉得非常好奇。以下是来自cppreference::unique_ptrcppreference::shared_ptr的声明:

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

template< class T > class shared_ptr;

正如您所见,unique_ptr&#34; save&#34; 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在后​​一种情况下会成为非成员函数?

1 个答案:

答案 0 :(得分:20)

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

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

  

由于删除器不属于该类型,因此更改分配策略不会破坏源或二进制兼容性,也不需要重新编译客户端。

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

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

另一方面,

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