164-C++学习第十四弹(唯一性,关系型智能指针)

auto_ptr的不好之处
在这里插入图片描述

unique_ptr(唯一性智能指针)

在这里插入图片描述
唯一性智能指针在任何一时刻只能有一个智能指针拥有此对象的拥有权
内存管理都在#include< memory >中(包含了智能指针)
在这里插入图片描述

这种实现和auto_ptr的实现方法一样

书写unique_ptr智能指针
在这里插入图片描述
在后期要重写这里的delete,为了克服auto不能识别单个对象还是数组的问题
在这里插入图片描述
这里的实现也和auto_ptr的实现一样

书写unique_ptr智能指针
在这里插入图片描述
我们需要判断智能指针是否有资源
在这里插入图片描述
在这里插入图片描述
程序正常运行
这里if里面要的是bool值
在这里插入图片描述
运行截图如下
在这里插入图片描述
书写unique_ptr智能指针
在这里插入图片描述
重载bool()

在这里插入图片描述
在这里插入图片描述
仍然有置换操作
把Object(10)的对象析构掉,新指向Object(20)
书写unique_ptr智能指针
在这里插入图片描述
在这里插入图片描述
也有release操作释放资源
唯一性智能指针可以判断有没有资源
书写unique_ptr智能指针
在这里插入图片描述
资源的交换,必须同类型
在这里插入图片描述

书写unique_ptr智能指针
在这里插入图片描述
在这里插入图片描述
唯一性智能指针不允许拿一个对象构造另一个对象
书写unique_ptr智能指针
在这里插入图片描述
拷贝构造函数声明为私有(没有函数的实现)
目的是告诉编译器禁止使用它,也不会产生缺省的按位拷贝的拷贝构造函数
写了不实现 阻止产生缺省拷贝构造函数
C11中也可以这样写
在这里插入图片描述
在这里插入图片描述
unique_ptr智能指针不允许赋值
书写unique_ptr智能指针
在这里插入图片描述
不允许产生缺省赋值语句(C11标准)

不能拷贝构造,不能赋值

在这里插入图片描述
靠delete把new方法删除了,如果调动new,程序将报错(C11标准)

但是unique_ptr可以移动构造
在这里插入图片描述

pObja把资源给给pObjc,然后pObja和这个资源没有关系了

书写unique_ptr智能指针
在这里插入图片描述
unique_ptr智能指针允许移动赋值
在这里插入图片描述
把pObjb资源给给pObja,如果pObja原有资源,把原有的资源释放掉。

书写unique_ptr智能指针
在这里插入图片描述
_u是pObjb的别名,pObja用this指针,两者不相等,然后先执行_u.release();失去对资源的拥有权,资源给给p,然后赋值给当前对象,当前对象先把先前资源释放掉,然后p给当前对象的_ptr
另一种写法如下:
在这里插入图片描述
在这里插入图片描述
程序员需要关注内存的释放

如果使用unique_ptr智能指针
在这里插入图片描述
在这里插入图片描述
不需要考虑内存泄漏,不要担心内存的释放
当fun函数结束返回pobj,调动的是移动拷贝和移动赋值,临时对象(将亡值)
资源在对象之间转移,而对象一个一个被析构掉

在这里插入图片描述
这里要拿pobj要去构造x,unique_ptr不干,因为拷贝构造函数已经删除了。

如果确实想把对象拥有权给出
在这里插入图片描述
把pobj对象对资源的拥有权给x
在这里插入图片描述
在这里插入图片描述
资源的释放先于主函数来进行
把pobj的资源转移给x,x在fun函数里用的过程中,当fun结束,x局部对象结束,把x对资源的拥有权释放,主函数的fun()语句结束时pobj已经失去对资源的拥有权

unique_ptr智能指针如何删除数组和其他资源?

做一个默认删除器
在这里插入图片描述
unique_ptr模板含两个参数
在这里插入图片描述
模板类型参数(可以有默认值),删除器参数(默认删除器)

在这里插入图片描述

重写delete
在这里插入图片描述
两种写法等价
根据删除器进行删除
在这里插入图片描述
在这里插入图片描述
构建对象,构建唯一性智能指针,->,返回地址指向方法,打印出value值,函数结束,调动析构函数,返回删除器,删除器对象去调动重载(),最终把对象删除。

加头文件#include<stdio.h>
给出文件删除器
在这里插入图片描述
智能指针并不意味着只管理堆区对象,可以管理其他类型的对象,删除器不同。

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
创建一组对象,调用的是特化版本[],析构的时候,调动删除器,删除一组对象
在这里插入图片描述
在这里插入图片描述
形参不能给值
在这里插入图片描述

对于list来说,里面放的Object指针
return 0;函数要结束 ,能不能满足把结点释放,把指针指向的所指对象释放?new出来的对象一个一个删掉?
在这里插入图片描述
能不能满足以上?
不能办到!
因为析构函数调用,本身是析构指针本身,指针没有析构函数,无法识别是指针还是对象

加入智能指针
在这里插入图片描述

在这里插入图片描述
首先给的list,list的成员是一个智能指针,当我们构建一个头结点,头结点的数据域类型就是智能指针类型,push_back对象是一个智能指针,智能指针指向堆区的object 10。等等。。。
在这里插入图片描述
这里的一个个智能指针管理着一个个的对象
用迭代器去迭代它时,迭代器指向第一个位置,*it是智能指针,->对象方法
list要销毁,删除智能指针,智能指针调动自己的析构函数,自己的析构函数把new出来的对象也释放掉

智能指针unique_ptr和容器愉快玩耍不用操心生存期

唯一性智能指针场景

在这里插入图片描述
在这里插入图片描述
没有赋值语句的重载哦

在这里插入图片描述
把第一个结点的智能指针的拥有权转移给pobj
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
这种做法不行,第一个结点的拥有权已经转移了,变成空指针

调整做法
在这里插入图片描述

shared_ptr智能指针

在这里插入图片描述

一个指针mPtr指向对象,和一个引用计数mpRefCnt(有mPtr指针指向对象,mCnt计数)
在这里插入图片描述
在堆区

在这里插入图片描述
在这里插入图片描述
一个对象两个人在使用,引用计数计数共享型指针有2个

在这里插入图片描述
产生pObjc对象,也有两个域构成
在这里插入图片描述
一个对象3个人使用,引用计数为3
如果一个对象销毁,引用计数为2
如果为0,没有人使用,就释放了

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
仿写
原子操作头文件
在这里插入图片描述
在这里插入图片描述
给出默认删除器
在这里插入图片描述
在这里插入图片描述
不能这样定义
在这里插入图片描述
如果你的成员这种定义方案,无法达到共享性
构建pobja对象,一个成员是指针成员,一个成员是计数成员,指针成员指向对象,计数成员里的指针指向对象,引用计数为1
当我们拿pobja构建objb的时候,pobjb也有两个成员,一个指针成员,一个计数成员,指针成员指向pobja对象,计数成员的指针也指向pobja的对象,在这里插入图片描述
但是这两个对象的引用计数都为1
看不到彼此里的引用计数,
实际上我们定义的引用计数不是针对智能指针对象的,而是针对对象有几个智能指针来引用

要定义成指针
一个指针指向pobja对象,一个指针指向计数
当把pobja给pobjb时,一个指针指向pobja对象,一个指针指向计数
在这里插入图片描述
在这里插入图片描述
在这里的ptr空与否,如果是空,引用计数默认为0,但是也要建立一个引用计数,空指针也当做资源来看

在这里插入图片描述
在这里插入图片描述
当程序运行时,new上一个对象,对象给ptr,然后new上一个引用计数
在这里插入图片描述
重载 * ->
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
但是这个方法,引用计数为0,把资源删除了,但是没有把这个指针删除,原来的引用计数指针丢失了!
整个写共享智能指针,引用计数的指针都没有删除

资源转移的函数
在这里插入图片描述
在这里插入图片描述

执行由系统提供的共享型智能指针
创建对象obja,引用计数为1,obja构造objb,引用计数为2,当我们创建objc,是一个空的东西,引用计数空。当把objb转移给objc的时候,我们看到,objb变空了。移动转移,就是把资源转移
在这里插入图片描述
在这里插入图片描述
共享资源=,怎么处理呢?
在这里插入图片描述
修改构造函数
在这里插入图片描述
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/LINZEYU666/article/details/113481756