独占智能指针
文章参考:
1. 初始化:
特点:
相较于共享智能指针,独占智能指针(unique_ptr)的关键在于:同一时刻,只能有一个智能指针指向同一块内存。因此独占智能指针不允许使用拷贝构造函数和拷贝赋值函数。
初始化:
-
通过构造函数初始化:
unique_ptr<int> ptr1(new int(100));
-
通过移动构造函数/移动赋值函数:
unique_ptr<int> ptr1(new int(100)); unique_ptr<int> ptr2(move(ptr1)); unique_ptr<int> ptr3 = move(ptr1);
-
通过函数返回给其他的
std::unique_ptr
(本质上是返回一个右值,然后通过移动构造函数/移动赋值函数进行初始化):unique_ptr<int> func(){ return unique_ptr<int>(new int(100)); } int main(void){ unique_ptr<int> ptr = func(); return 0; }
2. 成员函数
2.1 reset
原型:
void reset( pointer ptr = pointer() ) noexcepter;
作用:
-
解除独占智能指针对于目标内存的管理:
unique_ptr<int> ptr1(new int(100)); ptr1.reset();
-
重新指定独占智能指针的目标内存:
unique_ptr<int> ptr1(new int(100)); ptr1.reset(new int(100));
2.2 get()
原型:
pointer get() const noexcept;
作用:
获取独占智能指针管理的原始地址。
3. 删除器
3.1 删除器类型
unique_ptr
在指定删除器时和shared_ptr
不同,unique_ptr
必须指定删除器的类型,这就带来了一个问题:如果我们使用lambda表达式定义删除器,lambda表达式有以下特性:
-
当lambda不捕获外部变量时,可以转化为一个函数指针。
using func_ptr = void(*)(int*); unique_ptr<int, func_ptr> ptr(new int(100), [](int* p){ delete p; });
-
如果lambda捕获外部变量,那么就相当于一个仿函数。因此下面的代码存在错误:
using func_ptr = void(*)(int*); // error。lambda捕获了外部变量的值,此时相当于一个仿函数,与函数指针不匹配。 /* unique_ptr<int, func_ptr> ptr(new int(100), [&](int* p){ delete p; }); */
因此,我们一般使用可调用对象包装器来指定独占智能指针的删除器类型:
unique_ptr<int, function<void(int*)>> ptr(new int(100),
[](int* p){
delete p;
});
3.2 数组删除器
和shared_ptr
的操作一致。