当前位置: 首页 > news >正文

QWeakPointer

特点:

  • 用于解决 QSharedPointer 可能导致的循环引用问题。
  • 不会增加对象的引用计数,不影响对象的生命周期。
  • 可以从 QSharedPointer 或者另一个 QWeakPointer 创建,用于在需要时保持对对象的非拥有者式引用。
  • 如果关联的 QSharedPointer 被释放,QWeakPointer 会自动置空,避免悬空指针问题。

这里重点说下循环引用,当两个或多个对象彼此持有对方的强引用时,就会形成循环引用。这种情况下,对象无法被正常释放,会导致内存泄漏。Qt 的 QWeakPointer 类是为了解决这个问题而引入的。

QWeakPointer 允许创建一个弱引用指向被QSharedPointer管理的对象,但不会增加该对象的引用计数。弱引用不会阻止对象的销毁,即使所有强引用都失效,对象的析构函数也能被正确调用。

下面是一个循环引用的示例:

#include <QSharedPointer>
#include <QWeakPointer>
#include <QDebug>class ObjectB;class ObjectA
{
public:ObjectA(const QString& name) : m_name(name) {}~ObjectA(){qDebug() << "ObjectA 析构函数,名称为" << m_name;}void setObjectB(const QSharedPointer<ObjectB>& objectB){m_objectB = objectB;}private:QString m_name;QSharedPointer<ObjectB> m_objectB;
};class ObjectB
{
public:ObjectB(const QString& name) : m_name(name) {}~ObjectB(){qDebug() << "ObjectB 析构函数,名称为" << m_name;}void setObjectA(const QSharedPointer<ObjectA>& objectA){m_objectA = objectA;}private:QString m_name;QSharedPointer<ObjectA> m_objectA;
};int main()
{QSharedPointer<ObjectA> objectA(new ObjectA("ObjectA"));QSharedPointer<ObjectB> objectB(new ObjectB("ObjectB"));objectA->setObjectB(objectB);objectB->setObjectA(objectA);qDebug() << "程序结束";return 0;
}

  

结果输出:

程序结束

如上,在 main 函数中,创建了两个 QSharedPointer,用于管理 ObjectA 和 ObjectB 对象的生命周期。然后,通过 setObjectB 和 setObjectA 函数,相互设置对方的强引用,这样就形成了循环引用,导致对象无法正常销毁,从而出现内存泄漏。

为了避免这个问题,将 m_objectB 和 m_objectA 至少一个声明为 QWeakPointer 类型,如下:

QSharedPointer<ObjectB> m_objectB -> QWeakPointer<ObjectB> m_objectB 
或
QSharedPointer<ObjectA> m_objectA -> QWeakPointer<ObjectA> m_objectA 

由于使用了 QWeakPointer,不会增加对象的引用计数,这样也就打破了循环引用。当 objectA 和 objectB 超出作用域时,它们的引用计数会递减,对象能够被正常销毁。修改后结果输出如下:

程序结束
ObjectB 析构函数,名称为 "ObjectB"
ObjectA 析构函数,名称为 "ObjectA"

完整的代码

#include <QSharedPointer>
#include <QDebug>
class MyClass
{
private:int m_value;
public:MyClass(int value) : m_value(value){qDebug() << u8"MyClass 构造函数,数值为" << m_value;}~MyClass(){qDebug() << u8"MyClass 析构函数,数值为" << m_value;}void setValue(int value){m_value = value;}int getValue() const{return m_value;}};class ObjectB;
class ObjectA
{
public:ObjectA(const QString& name) : m_name(name) {}~ObjectA(){qDebug() << u8"ObjectA 析构函数,名称为" << m_name;}void setObjectB(const QSharedPointer<ObjectB>& objectB){m_objectB = objectB;}private:QString m_name;QSharedPointer<ObjectB> m_objectB;
};
class ObjectB
{
public:ObjectB(const QString& name) : m_name(name) {}~ObjectB(){qDebug() << u8"ObjectB 析构函数,名称为" << m_name;}void setObjectA(const QSharedPointer<ObjectA>& objectA){m_objectA = objectA;}private:QString m_name;// QSharedPointer<ObjectA> m_objectA;//这里替换了弱指针QWeakPointer<ObjectA> m_objectA;
};

  

http://www.jsqmd.com/news/59247/

相关文章:

  • 2025年12月上海离婚纠纷律师推荐排行榜:专业能力、服务范围与用户评价对比分析
  • 2025烟台口碑好的短视频拍摄运营公司推荐
  • 基于MATLAB的CNN脑机接口P300模型实现方案
  • 2024锅炉消音器TOP厂家排名:连云港双雄凭什么领跑行业?
  • 数据防泄漏的核心理念
  • 智能花灯品牌推荐排行,大型花灯/定制花灯/大型户外花灯/花灯灯展/生肖花灯/巡游花灯/创意花灯/华景花灯/国潮花灯花灯制作厂家哪家好
  • 2025年12月上海离婚律所综合对比与推荐排行:五家专业机构深度解析与选择指南
  • 2025西北工业大学计算机考研复试机试真题
  • 2025西北大学计算机考研复试机试真题
  • 2025西安交通大学计算机考研复试机试真题
  • 2025西安电子科技大学计算机考研复试机试真题
  • 2025武汉大学计算机考研复试机试真题
  • WTAPI微信社群管理开发:全场景自动化运营方案
  • 2025北京大学计算机考研复试机试真题
  • 2025年口碑好的防伪企业推荐,防伪制造厂选哪家好?
  • 2025年欧式古典高端家具TOP10权威榜:谁更懂宫廷气质与豪宅生活
  • 一维小波变换信号去噪方法详解与实现
  • 从0开始重新学python+neo4j之环境搭建、虚拟机创建
  • [蚂蚁] 素体 第2节
  • Spug自动化部署工具的搭建与应用(Java部署)
  • 我真没招了-冲刺总结
  • linux找不到日志怎么办
  • PlantUML
  • 【文章管理系统团队】Alpha阶段Scrum冲刺第1天随笔
  • 水一篇博文
  • 2025 年 12 月烟台专升本,烟台专升本考试最新推荐,聚焦资质、案例、售后的十家机构深度解读!
  • 2025香港留学中介机构名单出炉了吗
  • 镂空钟表大师王者归来!HEBE的镂空制表艺术
  • 2025年12月有效卖家精灵优惠折扣码领取 卖家精灵优惠码使用教程
  • GEO优化哪家公司做得好?2025年权威推荐与深度解析