总结一下前文内容:

  1.智能指针通过RAII方法来管理指针:构造对象时,完成资源初始化;析构对象时,对资源进行清理及汕尾.

  2.auto_ptr,通过“转移所有权”来防止析构一块内存多次.(如何转移?详情看第二篇文章)

  3.scoped_ptr,不“转移所有权”而是禁止拷贝/赋值对象.(C++如何禁止拷贝对象?详情看第三篇文章)

  4.shared_ptr,通过"引用计数"的方法,来完成对象的拷贝/赋值.(引用计数怎么实现?详情看上篇文章)

  大致总结了一下前文后,我们开始讨论今天的内容:解决智能指针的循环引用问题!

  我们先来看一下这样的场景:

template<typename T>
struct ListNode{T _value;std::shared_ptr<ListNode> _prev;std::shared_ptr<ListNode> _next;ListNode(const T & value):_value(value),_prev(NULL),_next(NULL){}~ListNode(){std::cout<<"~ListNode()"<<std::endl;}
};void TestWeekPtr(){std::shared_ptr<ListNode<int>> sp1(new ListNode<int>(10)); std::shared_ptr<ListNode<int>> sp2(new ListNode<int>(20));sp1->_next = sp2;sp2->_prev = sp1;//构成死锁,出了函数作用域,也没有调用析构函数std::cout<<sp1.use_count()<<std::endl;  //sp1的引用计数std::cout<<sp2.use_count()<<std::endl;    //sp2的引用计数
}

  sp1指向sp2、sp2又指向sp1,这种情况,就好像两个人打架:互相抓住对方耳朵,A说你先松手,你不松我就不松;B说你先松,你不松我也不松.就这样一直僵持着.....

  那么,我们如何解决这样的问题呢?

  用weak_ptr!!!

template<typename T>
struct ListNode{T _value;weak_ptr<ListNode> _prev;weak_ptr<ListNode> _next;ListNode(const T & value):_value(value),_prev(NULL),_next(NULL){}~ListNode(){std::cout<<"~ListNode()"<<std::endl;}
};
void TestWeekPtr(){std::shared_ptr<ListNode<int>> sp1(new ListNode<int>(10)); std::shared_ptr<ListNode<int>> sp2(new ListNode<int>(20));sp1->_next = sp2;sp2->_prev = sp1;std::cout<<sp1.use_count()<<std::endl;std::cout<<sp2.use_count()<<std::endl;
}

  那么为什么用weak_ptr就可以解决循环引用的问题,简单点的来说:weak_ptr的构造和析构不会引起引用计数的增加或减少.

  最后,作为补充:weak_ptr必须与shared_ptr配合使用,不能单独使用.

转载于:https://www.cnblogs.com/qq329914874/p/6661578.html

【C++】智能指针简述(五):解决循环引用的weak_ptr相关推荐

  1. 解决循环引用--弱引用weak_ptr

    循环引用:  引用计数是一种便利的内存管理机制,但它有一个很大的缺点,那就是不能管理循环引用的对象.一个简单的例子如下: class parent; class children;typedef sh ...

  2. weak_ptr 的几个应用场景 —— 观察者、解决循环引用、弱回调

    weak_ptr 弱智能指针 Effecvive Modern C++ 使用std::weak_ptr 来代替可能空悬的 std:: shared_ptr . std::weak_ptr 可能的用武之 ...

  3. python垃圾回收机制为什么标记能解决循环引用问题_Python 垃圾回收机制和如何解决循环引用...

    引用计数:是一种垃圾收集机制,而且也是一种最直观,最简单的垃圾收集技术, 当一个对象的引用被创建或者复制时,对象的引用计数加 1:当一个对象的引用被销毁时,对象的引用计数减 1:当对象的引用计数减少为 ...

  4. NSTimer解决循环引用常见方法

    1. NSTimer的使用 常见使用场景如下: - (void)viewDidLoad {[super viewDidLoad];self.view.backgroundColor = [UIColo ...

  5. js深拷贝,解决循环引用

    概念 前提为拷贝类型为引用类型的情况下: 浅拷贝是拷贝一层,属性为对象时,浅拷贝是复制,两个对象指向同一个地址 深拷贝是递归拷贝深层次,属性为对象时,深拷贝是新开栈,两个对象指向不同的地址 浅拷贝的方 ...

  6. php 解决循环引用,excel循环引用如何解决

    excel循环引用如何解决? 方法一 需要找到"excel选项",这个地方在Office 2003版本里的"工具"选项里,而在Office 2007版本里不好找 ...

  7. java中出现循环问题如何解决_java如何解决循环引用

    Excel 循环引用产生的原因及解决方法 来源:excel 格子社区 我们打开 ... (Garbage Collection Thread) , 来跟踪每一块分配出去的内存空间, Java 虚拟机 ...

  8. block为什么用copy以及如何解决循环引用

    在完成项目期间,不可避免的会使用到block,因为block有着比delegate和notification可读性更高,而且看起来代码也会很简洁.于是在目前的项目中大量的使用block. 之前给大家介 ...

  9. Flask-分开Models解决循环引用

    在之前我们测试中,所有语句都在同一个文件中,但随着项目越来越大,管理起来有所不便,所以将Models分离. 基本的文件结构如下 \-–app.py \-–models.py from flask im ...

最新文章

  1. 从前端程序员的视角看小程序的稳定性保障
  2. 梯度下降法与牛顿法的比较
  3. c语言字符串去重简单,C语言实现简单飞机大战
  4. 宜昌远安谋定功能性-农业大健康·万祥军:绿色和谐新路
  5. php获取随机图片,PHP 随机显示某张图片
  6. EFCore之增删改查
  7. mysql connector c编程_MySQL数据库之MySQL Connector 编程
  8. java多线程 run start_java多线程中run和start区别
  9. MySQL字符串拼接函数使用
  10. Cisco 模拟器rstp生成树
  11. 微信朋友圈装x代码_微信朋友圈写入代码 微信朋友圈代码大全
  12. 码code | 拒绝996,不用服务器也能高效开发小游戏
  13. oracle10g dblink优化,dblink如果很慢可以用这种方式优化
  14. 原生Winows7系统添加USB3.0的驱动
  15. 菜孔孔学python--集合
  16. Python Tensorflow + CNN + Opencv 英雄联盟小地图识别,LOL Minimap Scanner
  17. C语言中sort函数的用处
  18. 自动化测试C语言程序,初级自动化测试笔试题
  19. PL/SQL中的dual表含义和用法
  20. Pytorch squeeze()的简单用法

热门文章

  1. Dubbo详解-说明(一)
  2. 20145233《网络对抗》Exp8 Web基础
  3. 代理模式【介绍、静态代理、动态代理、入门、应用】
  4. docker 安装ElasticSearch 6.x
  5. spring mvc4 笔记
  6. 为什么说dubbo的声明式缓存不好用!!!
  7. Spark资源分配异常闪Bug
  8. jquery源码解析:代码结构分析
  9. 为什么要设置Java环境变量(详解)
  10. Orchard CMS前台页面为什么没有Edit链接?