Qt智能指针--QWeakPointer

文章目录

    • 概述
    • 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 
#include 
#include 
#include class Children;
class Parent
{
public:~Parent(){qDebug() << __FUNCTION__;}QSharedPointer m_pChildren;
};
class Children
{
public:~Children(){qDebug() << __FUNCTION__;}QSharedPointer 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(new Parent());QSharedPointer children(new Children());if(parent && children){parent->m_pChildren = children;children->m_pParent = parent;}
}

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

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

QSharedPointer m_pChildren;QSharedPointer m_pParent;

改成

QWeakPointer m_pChildren;QWeakPointer m_pParent;

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

~Children
~Parent

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

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


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部