目录
上一章节内容
unique_ptr指针
开门见山
这一章节我们来了解unique指针
什么是unique_ptr指针
unique_ptr是一种独占所有权的智能指针,同一时间只能有一个unique_ptr指向一个对象,当unique_ptr被销毁时,对象也会被释放。unique_ptr不能被复制,只能通过移动语义转移所有权。
unique的特点
- 基于排他所有权模式——两个指针不能指向同一个资源
- 无法进行左值unique_ptr复制构造,也无法进行左值复制赋值操作,但允许临时右值赋值构造和赋值,也就是让程序员明白这么做的后果
- 保存指向某个对象的指针,当它本身离开作用域时会自动释放它指向的对象。
- 在容器中保存指针是安全的
例子
#include <iostream>
#include <memory>
#include <vector>
using namespace std;
int main()
{
unique_ptr<string> p1(new string("hello"));
unique_ptr<string> p2(new string("hi"));
cout << "p1:" << p1.get() << endl;
cout << "p2:" << p2.get() << endl;
//p1 = p2; // 禁止左值赋值
//unique_ptr<string> p3(p2); // 禁止左值赋值构造
unique_ptr<string> p3(std::move(p1));
p1 = std::move(p2); // 使用move把左值转成右值就可以赋值了
cout << "p1 = p2 赋值后:" << endl;
cout << "p1:" << p1.get() << endl;
cout << "p2:" << p2.get() << endl;
return 0;
}
结果
p1:000002406200C750
p2:0000024062014CD0
p1 = p2 赋值后:
p1:0000024062014CD0
p2:0000000000000000
D:\C++\调试\x64\Debug\调试.exe (进程 21000)已退出,代码为 0。
要在调试停止时自动关闭控制台,请启用“工具”->“选项”->“调试”->“调试停止时自动关闭控制台”。
按任意键关闭此窗口. . .
在unique_ptr当中,p1=p2这样的赋值是非法的,不允许的
必须要用
unique_ptr<string> p3(std::move(p1));
把p1的值赋值给p2,同时把p1的值给清空,这是符合我们的直觉的
这样可以让程序员清楚自己做了什么,防止报错时无法排查
容器中
同理在容器中也是一样,这样也是不被允许的
vec[0] = vec[1];
这样做才是正确的
vec[0] = std::move(vec[1]);
支持对象数组的内存管理
你在unique_ptr可以这样定义,而auto_ptr不行
unique_ptr<char[]> array(new char[10]);
构造,赋值,释放
除此之外构造,赋值,释放都是和auto_ptr指针是一样的(具体可以查看上一节内容)
auto_ptr以及unique_ptr的排他性
auto_ptr<string> p1;
string *str = new string("abc");
p1.reset(str); // p1托管str指针
auto_ptr<string> p2;
p2.reset(str);
// 此时p1已经没有托管内容指针了,为NULL,在使用它就会内存报错!
cout << "str:" << *p1 << endl;
在这之中开始时p1托管str的指针,后面p2接管str指针的同时会把p1的托管给取消,这样p1指针指向的就是NULL(空),从而报错。
这是因为auto_ptr与unique_ptr的排他性
shared_ptr指针
这时我们就要利用到接下来讲的shared_ptr指针了