unique_ptr独占的智能指针
2.1 定义
unique_ptr
是一个独占型的智能指针,它不允许其他的智能指针共享其内部的指针,不允许通过赋值将 一个unique_ptr
赋值给另一个unique_ptr
。
unique_ptr<T> p1(new T);
unique_ptr<T> p2 = p1; // 报错,不能复制
但可以通过std::move
来转移到其他的unique_ptr
,这样它本身就不再拥有原来指针的所有权了。例如:
unique_ptr<T> p1(new T);
unique_ptr<T> p2 = std::move(p1); // 正确
在c++14当中加入了std::make_unique
,c++11中加入的是std::make_shared
。 使用new的版本重复了被创建对象的键入,但是make_unique函数则没有。
auto upw1(std::make_unique<Widget>()); // with make func
std::unique_ptr<Widget> upw2(new Widget); // without make func
2.2 与shared_ptr的区别
-
C++17中的shared_ptr才支持数组
-
unique_ptr需要确定删除器的类型,所以不能像shared_ptr那样直接指定删除器,得这样写:
std::shared_ptr<int> ptr3(new int(1), [](int *p){delete p;}); // 正确 std::unique_ptr<int> ptr4(new int(1), [](int *p){delete p;}); // 错误 std::unique_ptr<int, void(*)(int*)> ptr5(new int(1), [](int *p){delete p;}); //正确
使用的时候会发现,这里的捕获列表加了
&
或者=
就会报错。lambda 表达式的捕获列表(capture list)用于指定 lambda 表达式如何访问外部变量。当你为 lambda 表达式添加捕获列表(如&
或=
)时,lambda 表达式的类型会发生变化:从函数指针(如void(*)(int*)
)
变成了仿函数(闭包类型(closure type))。综上:使用unique_ptr
的时候指定的是void()(int)类型,现在的lamba表达式是闭包类型,所以报错。需要将
std::unique_ptr
的删除器类型改为std::function<void(int*)>
,因为std::function
可以存储任意可调用对象(包括有捕获的 lambda 表达式)。std::unique_ptr<int, std::function<void(int*)>> ptr5(new int(1), [&](int *p) {delete p;});
-
应用需求不同:如果希望只有一个智能指针管理资源或者管理数组就用unique_ptr,如果希望多个智能指针管理同一个资源就用shared_ptr。