智能指针 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);

 

posted @ 2020-06-07 13:06  min_zhi  阅读(414)  评论(0)    收藏  举报