shellmad-23_C++新特性 weak_ptr的提出及解决循环引用的思路

深入分析shared_ptr与weak_ptr的实现

stl中使用了shared_ptr来管理一个对象的内部指针,并且使用了weak_ptr来防止前面所提到的shared_ptr循环引用的问题。

接下来简单的分析shared_ptr和weak_ptr的实现,最后通过自己写代码来模拟shared_ptr和weak_ptr,达到深入学习的目的:

测试代码如下:

#include "stdafx.h"
#include <memory>

int _tmain(int argc, _TCHAR* argv[])
{   
    std::shared_ptr<int> sptr(new int(3)); // 首先创建一个指针, 交给智能指针管理
    // sptr, sptr2指向同一个内容, 引用计数为2
    std::shared_ptr<int> sptr2 = sptr; // 同时赋值给另外一个智能指针
	// 引入了第3个指针
    std::weak_ptr<int> wptr = sptr;
	
	// 弱指针如果想使用强指针, 必须先判断, 判断弱指针是否与强指针有一定的关联, 并且强指针是存在的
    if (!wptr.expired()){
        
        std::shared_ptr<int> sptr3 = wptr.lock(); // 使用的时候, 需要通过lock函数的提升, 变为强指针, 接下来就可以使用这个指针了
    }

    return 0;
}

代码运行分析:
出现了强指针和弱指针引用的次数

我们之前实现智能指针的时候, 也有引用计数, 当时只有1个数字, 而这里出现了2个数字
在这里插入图片描述
重新开程序, 单步走, 第1次只有1个强指针引用次数
在这里插入图片描述
继续单步走, sptr2 = sptr;, 强引用次数变成了2

在这里插入图片描述
当我们, 把强指针赋值给了弱指针后, std::weak_ptr<int> wptr = sptr;
多了一个弱引用1, 表示有一个弱指针的存在, 在关联强指针
在这里插入图片描述
这时候, 想使用强指针的话, 先用弱指针判断有没有关联, if (!wptr.expired()){
如果和强指针有关联, 那么通过wptr.lock()提升为强指针 std::shared_ptr<int> sptr3 = wptr.lock();

然后弱指针引用次数仍然为1, 强指针引用次数变为了3
在这里插入图片描述

需要有两个问题需要思考:

  1. 为什么会存在强弱指针的计数?
  2. 强弱指针计数的用途是什么? 具体的代码实现是什么 (其实和第1个问题重合, 如果知道了为什么存在, 也就知道了用途)

上节课循环引用的总结:
在这里插入图片描述
如何来避免这种情况

如果引用次数,两者都是2的话, 永远解决不了这个问题, 因为他们两个互相引用, 为了打破这个闭环, 这2者中有一个引用次数最好为1

但是减了1次, 统计的次数就会不准确, 讲道理本来是2次, 现在减为了1次, 不准确了啊

所以为了解决次数不准确的问题, C++不得不再引入一个新的概念, 叫弱指针

使用弱指针会存在一个问题, 弱指针和原来对象是关联的, 但是不能直接使用, 直接使用需要通过lock函数来进行提升, 当使用的时候, 使用lock函数提升一下, 就会增加相应的强引用次数, 这样做的话就可以打破闭环, 因为用了弱指针, 弱指针不影响原来的引用次数, 所以原来的引用次数为1

所以弱指针是这么来的, 把1个2减少为了1, 打破了闭环, 从而让他得以释放
弱指针和强指针有关联

为了管理强指针本身的对象, 我们引入强指针的引用次数

为了管理弱指针, 我们提供了weak_ptr_uses_count, 通过弱指针的使用次数, 来管理弱指针对象
通过share_ptr_uses_ptr来管理原来的指针

所以这里就分开了, 新增了弱指针的概念, 就不得不加一个weak_ptr_uses_count将它关联起来
share_ptr_uses_count保持不变
通过这么样的一个处理, 解决了循环引用

在这里插入图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值