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;
};

  

posted @ 2025-12-03 11:01  家煜宝宝  阅读(0)  评论(0)    收藏  举报