C++ Qt 中的 QPointer、QSharedPointer 和 QWeakPointer 类之间有什么区别?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/22304118/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
What is the difference between QPointer, QSharedPointer and QWeakPointer classes in Qt?
提问by Nejat
I have read from the Qt documentations about QPointer
, QSharedPointer
and QWeakPointer
classes. It says:
我从 Qt 文档中阅读了关于QPointer
,QSharedPointer
和QWeakPointer
classes 的内容。它说:
QPointer
is a template class that provides guarded pointers to Qt objects and behaves like a normal C++ pointer except that it is automatically set to 0 when the referenced object is destroyed and no "dangling pointers" are produced.QSharedPointer
class holds a strong reference to a shared pointer.QWeakPointer
class holds a weak reference to a shared pointer.
QPointer
是一个模板类,它提供指向 Qt 对象的受保护指针,其行为类似于普通的 C++ 指针,除了当引用的对象被销毁并且不产生“悬空指针”时它会自动设置为 0。QSharedPointer
类持有对共享指针的强引用。QWeakPointer
类持有对共享指针的弱引用。
My questions is "What is the difference between these classes?". i.e what is the difference between a pointer to an object and a reference to a pointer? Are they all pointers to objects with different mechanisms and behaviors?
我的问题是“这些课程之间有什么区别?”。即指向对象的指针和指向指针的引用有什么区别?它们都是指向具有不同机制和行为的对象的指针吗?
回答by king_nak
QPointer:QPointer
can only point to QObject
instances. It will be automatically set to nullptr
if the pointed to object is destroyed. It is a weak pointer specialized for QObject
.
QPointer:QPointer
只能指向QObject
实例。nullptr
如果指向的对象被销毁,它将自动设置为。它是一个专门用于 的弱指针QObject
。
Consider this fragment:
考虑这个片段:
QObject *obj = new QObject;
QPointer<QObject> pObj(obj);
delete obj;
Q_ASSERT(pObj.isNull()); // pObj will be nullptr now
QSharedPointer
A reference-counted pointer. The actual object will only be deleted, when all shared pointers are destroyed. Equivalent to std::shared_ptr
.
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
Note that as long as there is a shared pointer, the object is not deleted!
注意只要有共享指针,对象就不会被删除!
QWeakPointer:
Can hold a weak reference to a shared pointer. It will not prevent the object from being destroyed, and is simply reset. Equivalent to std::weak_ptr
, where lock
is equivalent to toStrongRef
.
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());
This can be used if you need access to an object that is controlled by another module.
如果您需要访问由另一个模块控制的对象,则可以使用此方法。
To use a weak pointer, you must convert it to a QSharedPointer
. You should never base a decision on the weak pointer being valid. You can only use data()
or isNull()
to determine that the pointer is null.
要使用弱指针,您必须将其转换为QSharedPointer
. 您永远不应该根据弱指针是否有效来做出决定。您只能使用data()
或isNull()
来确定指针为空。
Generally, to use a weak pointer, you must convert it to a shared pointer since such an operation ensures that the object will survive for as long as you are using it. This is equivalent to "locking" the object for access and is the only correct way of using the object pointed to by a weak pointer.
通常,要使用弱指针,您必须将其转换为共享指针,因为这样的操作可确保对象在您使用它时一直存在。这等效于“锁定”对象以进行访问,并且是使用弱指针指向的对象的唯一正确方法。
QScopedPointer:
This is just a helper class that will delete the referenced object when the pointer goes out of scope. Thus, binds a dynamically allocated object to a variable scope.
QScopedPointer:
这只是一个帮助类,当指针超出范围时将删除引用的对象。因此,将动态分配的对象绑定到变量作用域。
You can use this for RAII semantics for locals, e.g.:
您可以将此用于本地人的 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
}
The item will also be deleted in case of an exception
如果出现异常,该项目也将被删除
Another use case can be member variables of an object. Then you don't need to write a destructor for those:
另一个用例可以是对象的成员变量。那么你不需要为那些编写析构函数:
class MyClass {
public:
MyClass() : myPtr(new int) {}
private:
QScopedPointer<int> myPtr; // Will be deleted automatically when containing object is deleted
}