智能指针 unique_ptr
一、概述
1、独占式,同一时刻只能有一个unique_ptr 指针指向这个对象,当unique_ptr 被销毁的时刻,它所指向的对象也会被销毁。
2、初始化
unique_ptr p1(new int(10)); unique_ptr p2 = make_unique(10); // C++14中才有make_unique()方法,不支持删除器
二、常用操作
注意:不允许的操作 不能用unique_ptr 去初始化另一个unique_ptr ,独占式的智能指针,不支持复制操作。但是可以支持移动
1、移动语义
unique_ptr p1(new int(10)); unique_ptr p2 = std::move(p1); // 移动之后,p1为空,p2指向原来p1所指向的内存
2、release()
// 放弃对指针的控制权,切断了智能指针和其所指对象之间的联系,返回裸指针,将智能指针置空, // 返回在这个裸指针可以手动delete,也可以用来初始化另一个智能指针 unique_ptr p1(new int(10)); unique_ptr p2(p1.release()); // 注意:release()返回的裸指针所指的内存,如果没有被其他智能指针指向,则需要自己手动delete这个裸指针,否则会内存泄漏
3、reset()
unique_ptr p1(new int(10)); unique_ptr p2(new int(10)); p1.reset(); // 释放智能指针所指的对象,并将智能指针置空 p1.reset(p2); // 释放智能指针所指的对象,并将智能指针指向p2(新对象)
4、指向一个数组
unique_ptr<int[]> parray(new int[10]); // 注意要有[] parray[0] = 0; parray[1] = 1; // 与shared_ptr 指向数组的情况类似 // 注意:对于定义内容是数组的,没有解引用运算符 *parray[0] = 10; 这种写法是不对的
5、get()
返回智能指针保存的裸指针,这个裸指针不能手动delete 否则会影响原来unique_ptr 所指对象
6、转化成shared_ptr 类型
// 如果unique_ptr 为右值,就可以将它赋值给shared_ptr,shared_ptr接管原来unique_ptr 所拥有的内存 // 例子: unique_ptr MyFun(); // 函数申明 shared_ptr ps = MyFun(); // 返回值都是临时对象,是右值 unique_ptr p1(new int(10)); // p1为左值,不能直接赋值给shared_ptr shared_ptr p2 = std::move(p2); // 将左值转右值,执行后,p1为空,p2指向原来p1指向的内存
三、删除器
1、格式
unique_ptr<指向对象类型, 删除器类型名> 指针变量名;
2、删除器几种写法
void MyDelete(string* p) { delete p; p = nullptr; } typedef void(fp)(string); // (1)定义一个函数指针类型 using fp = void()(string); // (2)也可以用using来定义一个函数指针类型,和上一句作用相同 typedef deltype(MyDelete)* fp; // (3)这种写法比较少见,也是在定义一个函数指针 unique_ptr<string, fp> ps(new string("Hello"), MyDelete); // 后面只要传入函数名即可
3.lambda表达式写法
auto MyDelete = [](string* p){ // 把lambda表达式 理解成一个类 delete p; p = nullptr; } unique_ptr<string, deltype(MyDelete)> ps(new string("Hello"), MyDelete);
4.指定删除器额外说明
shared_ptr // 删除器影响指针类型,所以就算两个shared_ptr 删除器不同,只要指向对象类型相同,这两个shared_ptr就属于同一种类型 unique_ptr // 删除器会写入模板,会影响指针类型,所以删除器不同,就算指向的对象类型相同,也不是同一种类型
四、尺寸大小
unique_ptr 与裸指针尺寸相同,如果增加了自己的删除器,则unique_ptr 尺寸可能增加,也可能不增加。
1.lambda表达式这种删除器,尺寸没有变化
// MyDelete为 三.3 中的lambda表达式 unique_ptr<string, deltype(MyDelete)> ps(new string("Hello"), MyDelete);
2.定义一个函数作为删除器,尺寸发生变化,变成8字节
typedef void(fp)(string); unique_ptr<string, fp> ps(new string("Hello"), MyDelete);