⌚前言
自C++11后,推出了三个智能指针。其中 unique_ptr
和shared_ptr
可以指定删除器。
但两者的形式却不太一样,本文将带你了解两者的基础使用区别。
⏲️注意
weak_ptr
是专门用来作为共享指针的使用权的,是一种零时的所有权,是没有删除器的。
make_xxx
是专门用于创建的,参数也很简单,就是直接转发到构造函数中,不附带指定删除器。(但不排除以后可能会添加兼容删除器的版本,但个人认为实现起来会比较麻烦)
本文不考虑数组版本的特化。
⌚unique_ptr
⏲️说明
类型声明
template<
class T,
class Deleter = std::default_delete<T>
> class unique_ptr;
构造声明
unique_ptr( pointer p, ? d) noexcept;
unique_ptr( pointer p, ? d) = delete;
构造拥有 p 的 std::unique_ptr 对象,以 p 初始化存储的指针,并按下列方式初始化删除器 D(依赖于 D 是否为引用类型)。
a) 若 D 是非引用类型 A,则签名是:
unique_ptr(pointer p, const A& d) noexcept; // (1) (要求 Deleter 为不抛出可复制构造 (CopyConstructible) )
unique_ptr(pointer p, A&& d) noexcept; // (2) (要求 Deleter 为不抛出可移动构造 (MoveConstructible) )
b) 若 D 是左值引用类型 A&,则签名是:
unique_ptr(pointer p, A& d) noexcept;
unique_ptr(pointer p, A&& d) = delete;
c) 若 D 是左值引用类型 const A&,则签名是:
unique_ptr(pointer p, const A& d) noexcept;
unique_ptr(pointer p, const A&& d) = delete;
所有情况下删除器从 std::forward<decltype(d)>(d) 初始化。这些重载只有在 std::is_constructible<D, decltype(d)>::value 为 true 时才会参与重载决议。
说白了,就是模板的第二个删除器的参数类型要和构造函数的类型匹配。
比如,模板参数是左值引用A&
,那构造函数也必须是左值引用A&
。
⏲️实例
其实只要知道原理,熟悉模板和函数对象的朋友很容易能构造出实例。
基于仿函数
#include <iostream>
#include <memory>
struct MyDeleter {
void operator()(int* p) const {
std::cout << __func__ << std::endl;
delete p;
}
};
int