176-C++学习第十六弹(共享型,弱智能指针)

讲解make_shared()

在这里插入图片描述
示例1:
在这里插入图片描述
**这种做法没有意义!**我们从堆区构建一个对象Object,地址给给指针op,当我们做共享指针pobja,pobjb后,会导致这个Object对象被重复释放。导致内存被重复释放。
在这里插入图片描述
在以后编程中,如果使用智能指针就不要再去使用裸指针

我们构建共享型智能指针有两种方式
在这里插入图片描述
两种方法都是从堆区new构建对象
在这里插入图片描述
make_shared()的方法的特点是:调动Object的构造函数,把括号里的值作为其构造函数的实参,去构建对象

1、用原生指针去创建

在这里插入图片描述
在这里插入图片描述
要创建2次,第1次去创建Object这个对象,shared_ptr有一个指针指向Object对象。shared_ptr还要有一个指针去指向引用计数。第2次去创建引用计数。引用计数有两部分构成:观察者引用计数(mCnt_w)和真实拥有者引用计数(mCnt_s)。
也就是说,我们用普通的方式去创建,采取的就是上图创建方式。
在这里插入图片描述
内存在构建时构建2次,释放的时候也得释放2次。
如果我们没有weak_ptr智能指针,mCnt_w=0,我们在构建pObj对象,new2次空间,一次指向Object对象,一次指向引用计数,当没有任何对象去共享Object对象的时候,引用计数为0,我们把Object对象释放,我们把引用计数释放,分2次释放。

如果我们还有去构建weak_ptr智能指针
在这里插入图片描述

weak_ptr也指向了引用计数,观察者引用计数变为1,当真实拥有者(mCnt_s=0),pObj对象要销毁时,只能把Object对象销毁,不能去释放引用计数对象,只有当弱智能指针销毁时,观察者引用计数变为0,才能去销毁释放引用计数对象。
在这里插入图片描述

2、用make_shared()方法构建

在这里插入图片描述

在这里插入图片描述
特点是同时分配好引用计数和对象。shared_ptr的两个指针,一个指向引用计数,一个指向Object对象。
对内存只进行一次操纵!

任何的计数方法,我们应该考虑是否适合当时的环境,场景,而不去讨论这有什么优点,那有什么缺点

在这里插入图片描述

下面这种写法,会出现什么情况?

在这里插入图片描述
这里的步骤:第一步:构建Object对象,第二步:调动couldThrowException函数,第三步构建共享型智能指针,

**如果我们第一步构建完Object对象,执行第二步couldThrowException函数可以正常执行,**没有抛出异常,返回12.23,接着构建智能指针,此智能指针的一个指针指向Object对象,一个指针指向引用计数,引用计数为1,引用计数里的一个指针指向Object对象,构建完成之后,调动doSomething函数,把12.23给d,把无名对象给pt,调动移动构造。然后程序向下执行。没问题。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

**如果是我们第一步构建完Object对象,执行第二步couldThrowException函数抛出异常,**造成doSomething函数在调动时抛出异常,此函数就不调动了,我们的共享型智能指针就没有产生,我们的Object对象就没有被销毁,造成了我们的内存泄漏

在这里插入图片描述
在这里插入图片描述
对象并没有被析构掉!

在这里插入图片描述
在这里插入图片描述
所以我们使用make_shared()使得第一步和第三步挨着一起
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
不存在内存的泄漏!
make_shared()把对象和引用计数放在同一个空间,同一时间去创建

在这里插入图片描述
在这里插入图片描述
如果我们Object对象的空间过大,如果使用make_shared来管理内存,当shared_ptr生存期到了,真实拥有者为0,析构Object对象,但是并没有回收这部分空间。只有当weak_ptr智能指针销毁时(生存期到达了),观察者引用计数为0,整个对象空间才可以被释放
对象很大,相当于有很大一块内存被无意义地锁住一段时间。
因为整个空间是一次分配好的,堆内存管理,不能从中间开始释放
在这里插入图片描述
这种做法是错误的!

缩减指针的正确做法
在这里插入图片描述
示例:
在这里插入图片描述
运行结果如下
在这里插入图片描述
在这里插入图片描述
增加代码
在这里插入图片描述
wp生存期不到,objlist.front()就不销毁
在这里插入图片描述
实际上空间并没有释放

在这里插入图片描述
头结点不做赋值。我们执行objlist.pop_front(),把第一个结点删除了,真实拥有者引用计数为0,把Object对象也析构了,但是观察者引用计数为1,堆区的一整块空间并没有被释放。

auto,unique_ptr

auto:依次访问容器的元素,x是容器里的类型(唯一型智能指针)
在这里插入图片描述
在这里插入图片描述

如果编写成下面这种情况
在这里插入图片描述

加上引用&,引用list每一个元素,x就是一个一个元素的别名。auto的特点是可以推断出元素的类型(唯一性智能指针)
如果没有&,要把唯一性智能指针的值拷贝起来给x,但是唯一性智能指针的拷贝构造函数是被删除的。导致容器里的智能指针没有办法进行拷贝给x

下面这种做法是可以的(转移拥有权)
在这里插入图片描述
在这里插入图片描述
修改代码如下
在这里插入图片描述
运行程序,程序崩溃
在这里插入图片描述
在这里插入图片描述
修改代码如下
在这里插入图片描述
程序正常运行
在这里插入图片描述
是因为重载了bool()
在这里插入图片描述
在这里插入图片描述

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

林林林ZEYU

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值