1、是什么?
一个unique_ptr “拥有”它所指向的对象。与shared_ptr 不同,某个时刻只能有一个unique_ptr 指向一个给定对象。当unique_ptr 被销毁时,它所指向的对象也被销毁。
2、怎么用?
- 如何声明一个unique_ptr 对象?
unique_ptr<int> p1;
- 如何初始化一个unique_ptr 对象?
不像shared_ptr 有一个make_shared 的标准库函数返回一个unique_ptr。只能直接初始化一个unique_ptr。
由于一个unique_ptr 拥有它指向的对象,因此不支持普通的拷贝或赋值操作。
unique_ptr<string> p1(new string("Hello Word!")); // 直接初始化
unique_ptr<string> p2(p1); // 错误:不支持拷贝
unique_ptr<string> p3;
p3 = p1; // 错误: 不支持赋值
虽然不能拷贝或赋值unique_ptr,但是我们可以通过release 或 reset 将指针的所有权从一个(非const)unique_ptr 转移给另一个unique_ptr。
// u.release() u放弃对指针的控制权,返回u 当前保存的C指针,并将u 置为空
unique_ptr<string> p2(p1.release()); // 把p1 的控制权转移给p2
// u.reset()
// u.reset(q) 如果提供了内置指针q,令u 指向这个对象;否则将u 置为空
p2.reset(p1.release()); // reset 释放了p2 原来指向的内存
- 传递unique_ptr 参数和返回unique_ptr
不能拷贝unique_ptr 的规则有一个例外:我们可以拷贝或赋值一个将要被销毁的unique_ptr。
unique_ptr<int> clone(int p)
{
// 正确:从int* 创建一个unique_pt<int>
return unique_ptr<int>(new int(p));
}
unique_ptr<int> clone(int p)
{
unique_ptr<int> ret(new int(p));
// ...
return ret;
}
对于两端代码,编译器都知道要返回的对象将要销毁。在这种情况下,编译器执行一种特殊的“拷贝”。
- 向unique_ptr 传递删除器
容易出错的地方
1、思考如下code,为什么?
p2.release(); //错误:p2 不会释放内存,而且丢失了指针
auto p = p2.release(); // 正确:但必须记得delete(p)