![](/img/trans.png)
[英]Why unique_ptr with custom deleter won't work for nullptr, while shared_ptr does?
[英]Why does unique_ptr have the deleter as a type parameter while shared_ptr doesn't?
std::unique_ptr
模板有两个参数:指针的类型和删除器的类型。 第二个参数有一个默认值,所以你通常只写std::unique_ptr<int>
之类的东西。
std::shared_ptr
模板只有一个参数:指针的类型。 但是您也可以使用自定义删除器,即使删除器类型不在类模板中。 通常的实现使用类型擦除技术来做到这一点。
std::unique_ptr
没有使用相同的想法是否有原因?
部分原因是shared_ptr
无论如何都需要一个显式的控制块用于引用计数并且保留一个删除器并不是最重要的交易。 然而, unique_ptr
不需要任何额外的开销,并且添加它将是不受欢迎的 - 它应该是一个零开销类。 unique_ptr
应该是静态的。
如果你想要这样的行为,你总是可以在顶部添加你自己的类型擦除 - 例如,你可以拥有unique_ptr<T, std::function<void(T*)>>
,这是我过去所做的。
除了DeadMG指出的另一个原因之外,另一个原因是它可以编写
std::unique_ptr<int[]> a(new int[100]);
和~unique_ptr
将调用正确的delete
版本(通过default_delete<_Tp[]>
),这要归功于T
和T[]
专用。
来自C++ Primer(第 5 版)<\/strong><\/em> ,第 16.1.6 章 - 效率和灵活性
shared_ptr 和 unique_ptr 之间的明显区别在于它们在管理所持有的指针时使用的策略——一个类给了我们共享所有权; 另一个拥有它持有的指针。 这种差异对于这些类的作用至关重要。
这些类在让用户覆盖其默认删除器的方式上也有所不同。 我们可以通过在创建或重置指针时传递一个可调用对象来轻松地覆盖 shared_ptr 的删除器。 相反,删除器的类型是 unique_ptr 对象类型的一部分。 用户在定义 unique_ptr 时必须提供该类型作为显式模板参数。 因此,unique_ptr 的用户提供自己的删除器更加复杂。
通过在编译时绑定删除器,unique_ptr 避免了间接调用其删除器的运行时成本。<\/strong> 通过在运行时绑定删除器,shared_ptr 使用户更容易覆盖删除器。<\/strong>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.