unique_ptr 与 shared_ptr 中的删除器类型
Deleter type in unique_ptr vs. shared_ptr
当我发现标准以两种完全不同的方式定义指针可能拥有的删除器时,我觉得很好奇。这是来自 cppreference::unique_ptr and cppreference::shared_ptr 的声明:
template<
class T,
class Deleter = std::default_delete<T>
> class unique_ptr;
template< class T > class shared_ptr;
如您所见,unique_ptr "saves" 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
在后一种情况下是非成员函数?
在这里您可以找到智能指针的原始提案:http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2003/n1450.html
它非常准确地回答了你的问题:
Since the deleter is not part of the type, changing the allocation strategy does not break source or binary compatibility, and does not require a client recompilation.
这也很有用,因为为 std::shared_ptr
的客户端提供了更多的灵活性,例如 shared_ptr
具有不同删除器的实例可以存储在同一个容器中。
此外,因为 shared_ptr
实现无论如何都需要一个共享内存块(用于存储引用计数),并且因为与原始指针相比已经有一些开销,所以添加类型擦除删除器不是这里有很多大事。
另一方面,unique_ptr
旨在完全没有开销,每个实例都必须嵌入其删除器,因此使其成为类型的一部分是很自然的事情。
当我发现标准以两种完全不同的方式定义指针可能拥有的删除器时,我觉得很好奇。这是来自 cppreference::unique_ptr and cppreference::shared_ptr 的声明:
template<
class T,
class Deleter = std::default_delete<T>
> class unique_ptr;
template< class T > class shared_ptr;
如您所见,unique_ptr "saves" 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
在后一种情况下是非成员函数?
在这里您可以找到智能指针的原始提案:http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2003/n1450.html
它非常准确地回答了你的问题:
Since the deleter is not part of the type, changing the allocation strategy does not break source or binary compatibility, and does not require a client recompilation.
这也很有用,因为为 std::shared_ptr
的客户端提供了更多的灵活性,例如 shared_ptr
具有不同删除器的实例可以存储在同一个容器中。
此外,因为 shared_ptr
实现无论如何都需要一个共享内存块(用于存储引用计数),并且因为与原始指针相比已经有一些开销,所以添加类型擦除删除器不是这里有很多大事。
unique_ptr
旨在完全没有开销,每个实例都必须嵌入其删除器,因此使其成为类型的一部分是很自然的事情。