如题,我们今天要讲的是 C++11 引入的三种智能指针中的:weak_ptr。

在学习 weak_ptr 之前最好对 shared_ptr 有所了解。如果你还不知道 shared_ptr 是何物,可以看看另一篇文章:

【C++11新特性】 C++11智能指针之shared_ptr

1、为什么需要weak_ptr?

在正式介绍weak_ptr之前,我们先来回忆一下shared_ptr的一些知识。

我们知道shared_ptr是采用引用计数的智能指针,多个shared_ptr实例可以指向同一个动态对象,并维护了一个共享的引用计数器。

对于引用计数法实现的计数,总是避免不了循环引用(或环形引用)的问题,shared_ptr也不例外。

我们先来看看下面这个例子:

#include #include #include using namespace std;

class ClassB;

class ClassA{public:    ClassA() { cout <"ClassA Constructor..." <endl; }    ~ClassA() { cout <"ClassA Destructor..." <endl; }    shared_ptr pb;  // 在A中引用B};class ClassB{public:    ClassB() { cout <"ClassB Constructor..." <endl; }    ~ClassB() { cout <"ClassB Destructor..." <endl; }shared_ptr pa;  // 在B中引用A};int main() {shared_ptr spa = make_shared();shared_ptr spb = make_shared();    spa->pb = spb;    spb->pa = spa;// 函数结束,思考一下:spa和spb会释放资源么?}

上面代码的输出如下:

ClassA Constructor...ClassB Constructor...Program ended with exit code: 0

从上面代码中,ClassA和ClassB间存在着循环引用,从运行结果中我们可以看到:当main函数运行结束后,spa和spb管理的动态资源并没有得到释放,产生了内存泄露。

为了解决类似这样的问题,C++11引入了weak_ptr,来打破这种循环引用。

2、weak_ptr是什么?

weak_ptr 是为了配合 shared_ptr 而引入的一种智能指针,它指向一个由 shared_ptr 管理的对象而不影响所指对象的生命周期,也就是将一个 weak_ptr 绑定到一个 shared_ptr 不会改变 shared_ptr 的引用计数。

不论是否有 weak_ptr 指向,一旦最后一个指向对象的 shared_ptr 被销毁,对象就会被释放。

从这个角度看,weak_ptr更像是shared_ptr的一个助手而不是智能指针。

3、weak_ptr如何使用?

接下来,我们来看看weak_ptr的简单用法。

3.1如何创建weak_ptr实例

当我们创建一个weak_ptr时,需要用一个 shared_ptr 实例来初始化 weak_ptr,由于是弱共享,weak_ptr 的创建并不会影响 shared_ptr 的引用计数值。

示例:

int main() {    shared_ptr<int> sp(new int(5));    cout <"创建前sp的引用计数:" <endl;    // use_count = 1

    weak_ptr<int> wp(sp);    cout <"创建后sp的引用计数:" <endl;    // use_count = 1}

3.2如何判断weak_ptr指向对象是否存在

既然weak_ptr并不改变其所共享的shared_ptr实例的引用计数,那就可能存在weak_ptr指向的对象被释放掉这种情况。

这时,我们就不能使用weak_ptr直接访问对象。那么我们如何判断weak_ptr指向对象是否存在呢?

C++中提供了lock函数来实现该功能。

如果对象存在,lock()函数返回一个指向共享对象的shared_ptr,否则返回一个空shared_ptr。

示例:

class A{public:    A() : a(3) { cout <"A Constructor..." <endl; }    ~A() { cout <"A Destructor..." <endl; }

    int a;};

int main() {    shared_ptr sp(new A());    weak_ptr wp(sp);//sp.reset();if (shared_ptr pa = wp.lock())    {cout <a <endl;    }else    {cout <"wp指向对象为空" <endl;    }}

试试把sp.reset()这行的注释去掉看看结果有什么不同。

除此之外,weak_ptr还提供了expired()函数来判断所指对象是否已经被销毁。

示例:

class A{public:    A() : a(3) { cout <"A Constructor..." <endl; }    ~A() { cout <"A Destructor..." <endl; }

    int a;};

int main() {    shared_ptr sp(new A());    weak_ptr wp(sp);    sp.reset(); // 此时sp被销毁cout <endl;  // true表示已被销毁,否则为false}

代码输入如下:

A Constructor...A Destructor...1

3.3如何使用weak_ptr

weak_ptr并没有重载 operator->和 operator *操作符,因此不可直接通过weak_ptr使用对象,典型的用法是调用其lock函数来获得shared_ptr示例,进而访问原始对象。

最后,我们来看看如何使用weak_ptr来改造最前面的代码,打破循环引用问题。

class ClassB;

class ClassA{public:    ClassA() { cout <"ClassA Constructor..." <endl; }    ~ClassA() { cout <"ClassA Destructor..." <endl; }    weak_ptr pb;  // 在A中引用B};class ClassB{public:    ClassB() { cout <"ClassB Constructor..." <endl; }    ~ClassB() { cout <"ClassB Destructor..." <endl; }    weak_ptr pa;  // 在B中引用A};int main() {shared_ptr spa = make_shared();shared_ptr spb = make_shared();    spa->pb = spb;    spb->pa = spa;// 函数结束,思考一下:spa和spb会释放资源么?}

输出结果如下:

ClassA Constructor...ClassB Constructor...ClassA Destructor...ClassB Destructor...Program ended with exit code: 0

从运行结果可以看到spa和spb指向的对象都得到释放!

作者:Fred^_^

原文:https://blog.csdn.net/Xiejingfa/article/details/50772571

推荐阅读:

【C++11新特性】 C++11 智能指针之shared_ptr

移动端技术交流喊你入群啦~~~

推荐几个堪称教科书级别的 Android 音视频入门项目

Android Camera2 实现高帧率预览录制(附源码)

觉得不错,点个在看呗~

c++11新特性_【C++11新特性】 C++11智能指针之weak_ptr相关推荐

  1. 【C++11新特性】 C++11智能指针之weak_ptr

    http://blog.csdn.net/xiejingfa/article/details/50772571 原创作品,转载请标明:http://blog.csdn.net/Xiejingfa/ar ...

  2. qt 如何 指针 自动 释放内存_要是面试官再问你智能指针的问题,就拿这篇文章“盘他”!!!...

    前一段时间,有不少朋友问我关于智能指针的问题,并且反映经常会在面试中被面试官问到,所以今天小豆君就来讲讲我对智能指针的理解,希望能对大家有所帮助 既然讲智能指针,我们就先来看看它为什么会出现. 1 传 ...

  3. ES7新特性_介绍--JavaScript_ECMAScript_ES6-ES11新特性工作笔记047

    然后我们来看es7中的两个新特性 首先来看第一个,用来判断,数组中是否包含某个元素 mingzhu.includes('') 可以看到其实就是数组对象.includes 可以看到包含返回true 不包 ...

  4. ES11新特性_动态import---JavaScript_ECMAScript_ES6-ES11新特性工作笔记065

    然后我们再看一下,es11中提供的这个动态的import 这个是用来解决什么问题? 解决以前我们导入需要的js文件,都是怎么导入,把需要的都一次导入进来对吧,做不到 按需导入,这样会导致一个问题,就是 ...

  5. 广州的11个辖区_人才吸引力排名,广州11个区哪家强?

    导读:什么样的区域对人才最具吸引力? 广东海丝研究院推出的<广州11区人才吸引力指数报告>显示,广州11区中,天河区人才吸引力指数优势明显,位列第一,黄埔区.白云区.越秀区.南沙区紧随其后 ...

  6. 团队管理新思考_需要一个新的空间来思考讨论和行动

    团队管理新思考 andrew wong安德鲁·黄 Follow跟随 Sep 4 九月4 There is a need for a new space to think, discuss, and a ...

  7. idata 单片机 新唐_【nuvoton新唐8051单片机】NuTiny-SDK-N76E003开发板

    型号:NuTiny-SDK-N76E003 内核架构:8-bit 产品简介: N76E003为新唐高速1T 8051 单片机系列产品,提供18 KB Flash ROM.可配置Data Flash与高 ...

  8. mysql把用户权限授予新用户_如何创建新用户和授予MySQL中的权限

    什么是红色表示 用户需要输入或定制的生产线将在红色在本教程! 其余的应该主要是复制和粘贴. 关于MySQL MySQL是一个开源数据库管理软件,可帮助用户存储,组织和以后检索数据. 它有多种选项来授予 ...

  9. 学习新技能_如何学习新技能

    学习新技能 Lately I've been trying to analyze how long it takes me to learn a new skill. During the proce ...

最新文章

  1. eplan和西门子plc的对接_玩转西门子全集成自动化之TIA Selection Tool
  2. python代码壁纸-python设置windows桌面壁纸的实现代码
  3. Python动态网页爬虫技巧Selenium(一)
  4. lambda中的钩子函数
  5. Linux学习之系统编程篇:shm 共享内存及其操作函数
  6. 神器面世:让你快速在 iOS 设备上安装 Windows、Linux 等操作系统!
  7. Config配置文件的加解密
  8. linux PROC文件系统详解
  9. KMP算法(快速模式匹配)
  10. MySQL ALTER命令
  11. 哈佛大学单细胞课程|笔记汇总 (八)
  12. MRC522(2):超简易门禁
  13. C语言之预处理探究(三):头文件包含
  14. 禁止VirtualBox同步Guest系统的时间
  15. mysql是用啥语言写的_mysql源码是什么语言
  16. Ant Deign Pro - ProTable - 高级表格 通用打印组件
  17. CRM系统更换服务器,CRM系统三种常见安装实施解决方式
  18. Contiki开发日记·1——Instant-contiki环境搭建
  19. 北京信息科技大学计算机学院官网,北京信息科技大学教务处官网入口地址
  20. 腾讯优图贾佳亚:人工智能的多模态发展

热门文章

  1. html清除内部所有补白,如何清除行内元素之间的HTML空白
  2. C++的new运算符和delete运算符
  3. HDU 3652 B-number (数位DP)
  4. Mysql基础代码(不断完善中)
  5. IP trie树接口
  6. 2013年11月17日
  7. uva 10891 - Game of Sum
  8. 怎么用计算机弹that girl,抖音使用教程 抖音that girl 歌曲歌词介绍
  9. 打断点的方式_一位清华退休老教授:作为家长如果能管住孩子这3点,将来会成才...
  10. 贪心算法——洛谷(P1090)[NOIP2004]合并果子