先来看看什么C++入门谈到unique_ptr和shared_ptr:
$ 16.1.6.效率和灵活性
我们可以确定
shared_ptr不将删除器作为直接成员,因为删除器的类型直到运行时才知道.因为删除器的类型是a
unique_ptr类型的一部分,所以删除器成员的类型在编译时是已知的.删除器可以直接存储在每个unique_ptr对象中.
所以似乎shared_ptr没有直接的删除成员,但unique_ptr确实如此.然而,另一个问题的最高投票回答说:
如果将deleter作为模板参数提供(如
unique_ptr),则它是类型的一部分,您不需要在此类型的对象中存储任何其他内容.如果将deleteter作为构造函数的参数传递(如shared_ptr),则需要将其存储在对象中.这是额外灵活性的代价,因为您可以为相同类型的对象使用不同的删除器.
引用的两段完全相互矛盾,让我感到困惑.更重要的是,许多人说unique_ptr是零开销,因为它不需要将删除器存储为成员.但是,正如我们所知,unique_ptr有一个构造函数unique_ptr<obj,del> p(new obj,fcn),这意味着我们可以将删除函数传递给它,因此unique_ptr似乎已将删除函数存储为成员.真是一团糟!
当我发现标准定义std::unique_ptr并且std::shared_ptr以两种完全不同的方式关于指针可能拥有的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;
Run Code Online (Sandbox Code Playgroud)
正如您所看到的,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);
Run Code Online (Sandbox Code Playgroud)
有人可以解释这种差异背后的理性吗?我明显赞成这个概念,unique_ptr为什么这不适用于此shared_ptr?另外,为什么get_deleter在后一种情况下会成为非成员函数呢?
类型擦除 - 你怎么称呼它?
如何boost::shared_ptr存储其删除器以及如何boost::function存储其功能对象?
有没有教授这个技巧的教程?
使用类型擦除函数对象的运行时成本是多少?
假设我想使用带有unique_ptr的自定义删除器:
void custom_deleter(int* obj)
{
delete obj;
}
Run Code Online (Sandbox Code Playgroud)
为什么我要写这个:
std::unique_ptr<int, void(*)(int*)> x(new int, custom_deleter);
Run Code Online (Sandbox Code Playgroud)
而不是这个:
std::unique_ptr<int> x(new int, custom_deleter); //does not compile
Run Code Online (Sandbox Code Playgroud)
?
不能推断出删除器的类型吗?