当前位置: 首页 > 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.gsyq.cn/news/69681.html

相关文章:

  • 2025烟台口碑好的短视频拍摄运营公司推荐
  • 2024锅炉消音器TOP厂家排名:连云港双雄凭什么领跑行业?
  • 2025年12月上海离婚律所综合对比与推荐排行:五家专业机构深度解析与选择指南
  • 2025西安电子科技大学计算机考研复试机试真题
  • 2025北京大学计算机考研复试机试真题
  • 2025年口碑好的防伪企业推荐,防伪制造厂选哪家好?
  • 2025年欧式古典高端家具TOP10权威榜:谁更懂宫廷气质与豪宅生活
  • 一维小波变换信号去噪方法详解与实现
  • Spug自动化部署工具的搭建与应用(Java部署)
  • linux找不到日志怎么办
  • PlantUML
  • 【文章管理系统团队】Alpha阶段Scrum冲刺第1天随笔
  • GEO优化哪家公司做得好?2025年权威推荐与深度解析
  • 2025 年 12 月玻璃钢锚杆,全螺纹玻璃钢锚杆厂家最新推荐,精准检测与稳定性能深度解析
  • 2025 年 12 月三相变压器,节能变压器,隔离变压器厂家最新推荐,聚焦资质、案例、售后的十家机构深度解读!
  • 国产金仓数据库(KingBase)从零开始
  • 债务偿还规划工具:智能优化您的财务自由之路
  • jar文件解压缩操作
  • 20232327 2025-2026-1 《网络与系统攻防技术》实验八实验报告
  • 2025年杭州离婚律师权威推荐榜单:离婚纠纷/涉外离婚/离婚财产纠纷专业律师精选
  • 工业智能时序数据库 IoTDB 荣获 2025 苏州・常熟全国创新创业大赛总决赛二等奖
  • 正向传播与反向传播(神经网络思维的逻辑回归) - 教程
  • 半指手套厂家怎么选?2025皮手套厂家口碑榜
  • 2025年深圳子女抚养权律师推荐排行榜,哪个好?哪个靠谱?选哪个?网站网址及联系电话
  • 2025年pph管厂家权威推荐榜单:pp管件‌/pp聚丙烯管‌/pp塑料管‌源头厂家精选
  • 2025自动化巡检能力对比:自动化运维厂商如何破解合规与效率双重挑战?
  • 2025年上海离婚诉讼律师推荐排行榜,哪个好?哪个靠谱?选哪个?网站网址及联系电话
  • 基于Jousselme距离的改进D-S证据理论MATLAB实现
  • 2025年上海子女抚养权律师电话联系方式汇总: 核心城区资深律师官方联系方式及高效沟通指引
  • 2025年上海离婚律师电话联系方式汇总:上海核心区域专业律师联系方式及高效法律咨询指引