文章目录

  • 概述
  • QWeakPointer
  • 示例

概述

前面我们说到的QSharedPointer是一个强引用类型的智能指针,而QWeakPointer是一个弱引用类型的智能指针,和C++中的weak_ptr功能是一样的。

QWeakPointer 是为配合 QSharedPointer 而引入的一种智能指针,它更像是 QSharedPointer 的一个助手(因为它不具有普通指针的行为,没有重载operator*和->)。它的最大作用在于协助 QSharedPointer 工作,像一个旁观者一样来观测资源的使用情况。

QWeakPointer

QWeakPointer不能用于直接取消引用指针,但它可用于验证指针是否已在另一个上下文中被删除。并且QWeakPointer对象只能通过QSharedPointer的赋值来创建。

需要注意的是,QWeakPointer不提供自动转换操作符来防止错误发生。即使QWeakPointer跟踪指针,也不应将其视为指针本身,因为它不能保证指向的对象保持有效。

说了那么多,QWeakPointer到底有什么用呢?
答案就是:解除循环引用。

在概述中我们说到,QWeakPointer 是为配合 QSharedPointer 而引入的一种智能指针。而什么叫循环引用,就是说:两个对象互相使用一个 QSharedPointer成员变量指向对方(你中有我,我中有你)。由于QSharedPointer是一个强引用的计数型指针,只有当引用数为0时,就会自动删除指针释放内存,但是如果循环引用,就会导致QSharedPointer指针的引用永远都不能为0,这时候就会导致内存无法释放。
所以QWeakPointer诞生了,它就是为了打破这种循环的。并且,在需要的时候变成QSharedPointer,在其他时候不干扰QSharedPointer的引用计数。它没有重载 * 和 -> 运算符,因此不可以直接通过 QWeakPointer 访问对象,典型的用法是通过 lock() 成员函数来获得 QSharedPointer,进而使用对象。

示例

首先,我们来看一个QSharedPointer循环使用的示例:

#include <QWidget>
#include <QDebug>
#include <QWeakPointer>
#include <QSharedPointer>class Children;
class Parent
{
public:~Parent(){qDebug() << __FUNCTION__;}QSharedPointer<Children> m_pChildren;
};
class Children
{
public:~Children(){qDebug() << __FUNCTION__;}QSharedPointer<Parent> m_pParent;
};class Widget : public QWidget
{Q_OBJECTpublic:Widget(QWidget *parent = 0);~Widget();void test();
};
#include "widget.h"Widget::Widget(QWidget *parent): QWidget(parent)
{test();
}Widget::~Widget()
{qDebug() << __FUNCTION__;
}void Widget::test()
{QSharedPointer<Parent> parent(new Parent());QSharedPointer<Children> children(new Children());if(parent && children){parent->m_pChildren = children;children->m_pParent = parent;}
}

在构造函数中调用test()函数,执行完过后应该会自动释放parent和children对象,但是由于相互引用,在退出之前,引用计数为2,退出之后引用计数还是1,所以导致不能自动释放,并且此时这两个对象再也无法访问到。运行过后发现并没有进入到Parent和Children的析构函数中。这就导致了内存泄漏。

那么该如何解决这个问题呢?
很简单,直接将上述代码两个类中的成员变量声明

QSharedPointer<Children> m_pChildren;QSharedPointer<Parent> m_pParent;

改成

QWeakPointer<Children> m_pChildren;QWeakPointer<Parent> m_pParent;

这时候再次运行,就会看到输出:

~Children
~Parent

这是因为在test()退出之前引用计数是1,函数退出之后就自动析构,这就解除了上面的循环引用。

参考:
https://blog.csdn.net/Tanswer_/article/details/79039617

Qt智能指针--QWeakPointer相关推荐

  1. Qt智能指针--QSharedPointer

    文章目录 前言 QSharedPointer 值得一提 前言 Qt智能指针QSharedPointer 与 C++中的std::shared_ptr其作用是一样的,其应用范围比我们前面说到的QPoin ...

  2. Qt智能指针--QScopedPointer

    文章目录 概述 QScopedPointer const 限制 考虑一种情况 QScopedArrayPointer 概述 前一篇文章我们详细的介绍了QPointer的用法,那么,这里继续总结Qt的另 ...

  3. Qt 之 智能指针汇总

    来源 还有其他一些,做了一些汇总和测试,就不全列了. 文章目录: 一.垂悬指针的问题 二.Qt中的智能指针        1.QPointer        2.QSharedPointer & ...

  4. Qt源码剖析-智能指针

    目录 智能指针是什么? 为什么使用QT智能(smart)指针? Qt提供了哪些智能指针? QSharedPointer类模板(smart指针类)源码分析 1. QSharedPointer类模板对于模 ...

  5. 61、智能指针类模板

    1.智能指针 智能指针的意义 - 现代C++开发库中最重要的类模板之一 - C++中自动内存管理的主要手段 - 能在很大程度上避开内存相关的问题 STL中的智能指针 auto_ptr(#include ...

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

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

  7. 【QT小记】QT中智能指针的使用

    自定义两个类 class OnePiece { public:OnePiece() {qDebug() << QString("构造OP");}~OnePiece() ...

  8. Linux 内核里的“智能指针”【转】

    转自:http://blog.jobbole.com/88279/ 众所周知,C/C++语言本身并不支持垃圾回收机制,虽然语言本身具有极高的灵活性,但是当遇到大型的项目时,繁琐的内存管理往往让人痛苦异 ...

  9. Linux 内核里的“智能指针”

    Linux 内核里的"智能指针" from: http://begeek.cn/post/7889.html?ref=myread 众所周知,C/C++语言本身并不支持垃圾回收机制 ...

最新文章

  1. C# 获取图片的EXIF 信息
  2. 6410调试LCD屏AT050TN22遇到的问题
  3. 带你学python基础:面向对象编程
  4. 对拉格朗日乘子法与KKT的理解
  5. C#架构设计-程序运行时从xml配置文件中加载配置项并设置为全局变量
  6. 终极利器|一篇文章讲清楚Python虚拟环境
  7. 【若依(ruoyi)】打开新的选项卡
  8. python爬取方式_Python 爬虫入门(三)—— 寻找合适的爬取策略
  9. ASP.NET MVC3 中设置htmlAttribute
  10. WPF 如何实现颜色值拾取
  11. Android studio Error occurred during initialization of VM 问题解决
  12. Wait waitpid
  13. Django:ORM基本操作-CRUD,管理器对象objects,----->查询2(filter,exclude,get,查询谓词)
  14. 【干货】神策标签生产引擎架构
  15. Mybatis框架相关知识讲解
  16. 微软 Chromium Edge 禁用 Google?
  17. 实验室一块GPU都没有?这个云平台直接送3090、A100免费无门槛代金券!
  18. Photoshop去除拍摄手写笔记背景
  19. NC打印模板汇总技巧
  20. 计算机数字键盘无法输入数字,电脑数字键打不出数字怎么办?电脑数字键打不出数字的修复方法...

热门文章

  1. 随身风暴英雄接入云信,玩家即时通讯轻松搞定
  2. 九章算法 | 骑士的最短路线-BFS
  3. 沫沫金:2014最新全浏览器兼容左列固定右列自适应宽度技巧大公开
  4. VS2010 SP1
  5. Direct2D教程(一)Direct2D已经来了,谁是GDI的终结者?
  6. AL2018届校招笔试——自然语言处理
  7. 全闪存阵列的“五十度黑”
  8. Spring中ApplicationContext加载机制和配置初始化
  9. UVA 10271 Chopsticks
  10. 单片机驱动DM9000网卡芯片(详细调试过程)【下】