为什么std::unique_ptr包含删除函数签名作为模板定义的一部分有什么原因?
template<class T, class Deleter = std::default_delete<T>> class unique_ptr;
Run Code Online (Sandbox Code Playgroud)
VS
template< class T > class shared_ptr;
Run Code Online (Sandbox Code Playgroud)
Mik*_*son 10
一般目的unique_ptr是在唯一指针超出范围时提供指针的自动删除.当使用默认删除器(只是调用delete)时,unique_ptr除了指针本身之外,对象中不需要任何额外的数据成员.这意味着默认情况下unique_ptr几乎没有任何开销(因为大多数(如果不是全部)其功能都将被内联).
但他们也希望能够在有意义的特殊情况下提供更改删除器的选项.提供该选项的唯一方法,同时仍然能够优化它(存储和内联调用)是使其成为类型本身的静态部分,即通过模板参数.关键在于它unique_ptr是原始指针的最小开销替代方案.
在这种情况下shared_ptr,目标是完全不同的,现有的开销也是如此.共享指针实际上使用共享存储(动态分配),它存储指针,引用计数和删除对象.换句话说,已经有很大的开销和适当的位置放置删除对象而不会导致额外的每指针开销.此外,利用所有引用计数机制,与现有开销相比,虚拟调用(执行删除)的开销相形见绌.这就是为什么在共享指针中包含类型删除删除对象的方便功能的自然选择.
并且,如果要创建具有类型擦除删除器的唯一指针类型,则使用模板别名非常简单:
template <typename T>
using any_unique_ptr = std::unique_ptr< T, std::function< void(T*) > >;
Run Code Online (Sandbox Code Playgroud)
或者类似的东西,就像这个删除器一样:
template <typename T>
struct type_erased_delete {
std::function< void(T*) > f;
type_erased_delete() : f(std::default_delete<T>()) { };
template <typename Func>
type_erased_delete(Func&& aF) : f(std::forward<Func>(aF)) { };
void operator()(T* p) const { f(p); };
};
template <typename T>
using any_unique_ptr = std::unique_ptr< T, type_erased_delete<T> >;
Run Code Online (Sandbox Code Playgroud)