【发布时间】:2017-05-19 15:29:57
【问题描述】:
当我发现标准以两种完全不同的方式定义指针可能拥有的 Deleter 时,我觉得这非常奇怪。这是来自cppreference::unique_ptr 和cppreference::shared_ptr 的声明:
template<
class T,
class Deleter = std::default_delete<T>
> class unique_ptr;
template< class T > class shared_ptr;
如您所见,unique_ptr 将 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 在后一种情况下是非成员函数?
【问题讨论】:
-
有人将不得不挖掘原始提案,但我有根据的猜测:没有删除器作为模板参数使
shared_ptr更易于使用,但您需要支付类型擦除成本。将get_deleter设为成员将使编写带有shared_ptr<T>的通用代码更加乏味——您需要编写sp.template get_deleter<Deleter>()而不是get_deleter<Deleter>(sp)。这就是为什么std::get不是会员。 -
稍微扩展 @T.C.说,
unique_ptr的设计目标之一是它应该(非常接近)零开销。擦除删除器的类型很方便,但会引入擦除带来的运行时间开销,因此与shared_ptr相比,unique_ptr不太适合 -
您还应该注意,由于这种差异,即使
Base没有虚拟析构函数,shared_ptr<Base> p = make_shared<Derived>()也会做正确的事情。 proof.
标签: c++ c++11 shared-ptr unique-ptr