【问题标题】:What is the difference between QPointer, QSharedPointer and QWeakPointer classes in Qt?Qt 中的 QPointer、QSharedPointer 和 QWeakPointer 类有什么区别?
【发布时间】:2014-04-13 18:56:50
【问题描述】:

我已经阅读了关于 QPointerQSharedPointerQWeakPointer 类的 Qt 文档。它说:

  1. QPointer 是一个模板类,它提供指向 Qt 对象的受保护指针,其行为类似于普通的 C++ 指针,只是当引用的对象被销毁并且不产生“悬空指针”时它自动设置为 0。

  2. QSharedPointer 类持有对共享指针的强引用。

  3. QWeakPointer 类持有对共享指针的弱引用。

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

【问题讨论】:

  • 我不知道,你为什么不问QScopedPointer :)
  • 如果我知道这些学习其他人变得简单。
  • Relevant blog post. 忽略关于让 QWeakPointers 跟踪 QObjects 的部分——只需使用 QPointer 即可。

标签: c++ qt pointers qsharedpointer qpointer


【解决方案1】:

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:
这只是一个帮助类,当指针超出范围时将删除引用的对象。因此,将动态分配的对象绑定到变​​量范围。

您可以将其用于本地人的 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
}

如果出现异常,该项目也会被删除

另一个用例可以是对象的成员变量。那么你就不需要为那些写析构函数了:

class MyClass {
public:
    MyClass() : myPtr(new int) {}
private:
    QScopedPointer<int> myPtr; // Will be deleted automatically when containing object is deleted
}

【讨论】:

  • QPointer和QScopedPointer有什么区别?
  • @magrif 将 QScopedPointer 添加到我的答案中。
【解决方案2】:
  • QSharedPointerstd::shared_ptr
  • QWeakPointer : std::weak_ptr
  • QScopedPointer : std::unique_ptr
  • QPointer:没有等效的 STL。当 QObject 销毁时为空。

【讨论】:

    猜你喜欢
    • 2011-04-22
    • 2010-12-20
    • 2013-05-09
    • 2012-03-16
    • 2011-01-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多