我已经从Qt文档中阅读了有关QPointerQSharedPointerQWeakPointer类的信息。它说:

  • QPointer是一个模板类,它提供指向Qt对象的 protected 指针,并且其行为类似于普通的C++指针,不同之处在于,当引用的对象被销毁并且不生成“悬挂指针”时,它将自动设置为0。
  • QSharedPointer类拥有对共享指针的强引用。
  • QWeakPointer类持有对共享指针的弱引用。

  • 我的问题是“这些类之间有什么区别?”。即,指向对象的指针和指向指针的引用之间有什么区别?它们是否都是指向具有不同机制和行为的对象的指针?

    最佳答案

    QPointer:QPointer只能指向QObject实例。如果指向的对象被销毁,它将自动设置为nullptr。这是专门用于QObject的弱指针。

    考虑以下片段:

    QObject *obj = new QObject;
    QPointer<QObject> pObj(obj);
    delete obj;
    Q_ASSERT(pObj.isNull()); // pObj will be nullptr now
    

    QSharedPointer
    引用计数的指针。仅当销毁所有共享指针时,才会删除实际对象。等效于std::shared_ptr
    int *pI = new int;
    QSharedPointer<int> pI1(pI);
    QSharedPointer<int> pI2 = pI1;
    pI1.clear();
    // pI2 is still pointing to pI, so it is not deleted
    pI2.clear();
    // No shared pointers anymore, pI is deleted
    

    请注意,只要有共享指针,就不会删除该对象!

    QWeakPointer:
    可以保留对共享指针的弱引用。它不会阻止对象被破坏,只需重置即可。等效于std::weak_ptr,其中lock等效于toStrongRef
    int *pI = new int;
    QSharedPointer<int> pI1(pI);
    QWeakPointer<int> pI2 = pI1;
    pI1.clear();
    // No shared pointers anymore, pI is deleted
    //
    // To use the shared pointer, we must "lock" it for use:
    QSharedPointer<int> pI2_locked = pI2.toStrongRef();
    Q_ASSERT(pI2_locked.isNull());
    

    如果您需要访问由另一个模块控制的对象,则可以使用此方法。

    要使用弱指针,必须将其转换为QSharedPointer。您永远不应基于弱指针有效的决定。您只能使用data()isNull()来确定指针为空。

    通常,要使用弱指针,您必须将其转换为共享指针,因为这样的操作可确保对象在您使用该对象时将一直存在。这等效于“锁定”对象以进行访问,并且是使用弱指针指向的对象的唯一正确方法。

    QScopedPointer:
    这只是一个辅助类,当指针超出范围时,它将删除引用的对象。因此,将动态分配的对象绑定(bind)到变​​量作用域。

    您可以将其用于本地的RAII语义,例如:
    MyClass *foo() {
        QScopedPointer<MyClass> myItem(new MyClass);
        // Some logic
        if (some condition) {
            return nullptr; // myItem will be deleted here
        }
        return myItem.take(); // Release item from scoped pointer and return it
    }
    

    如有异常(exception),该项目也会被删除

    另一个用例可以是对象的成员变量。然后,您不需要为这些编写析构函数:
    class MyClass {
    public:
        MyClass() : myPtr(new int) {}
    private:
        QScopedPointer<int> myPtr; // Will be deleted automatically when containing object is deleted
    }
    

    09-07 02:41