QPointer类是一个模板类,它提供了指向QObject的guarded pointer
。
template <typename T> class QPointer
- 头文件:
#include <QPointer>
- cmake:
find_package(Qt6 COMPONENTS Core REQUIRED) target_link_libraries(mytarget PRIVATE Qt6::Core)
- qmake:
QT += core
详细说明
guarded pointer
是什么指针?
- 当其指向的对象(必须是QObject及其派生类)被销毁时,它会被自动置NULL
- 和C++普通指针
T *
相比:普通指针被删除之后会变成悬空指针 - 我们来看个代码:
QPointer<Test> t = new Test(); // Test类必须继承QObject
delete t; //对象被delete之后,t会自动置NULL,而不会成为悬挂(dangling)的野指针
if(t.isNull())
qDebug()<<"NULL";
guarded pointer
实现原理:
- 其对象析构时会执行QObject的析构函数,进而执行QObjectPrivate::clearGuards(this);,这也是基于其指向对象都继承自QObject的原因。
- QPointer对QMetaObject的相关操作做了简单的封装,这里的基本思想是在QPointer构造的时候调用QMetaObject::addGuard(&o),把T的指针加入QMetaObject内的一个哈希表中,
在QPointer析构的时候调用QMetaObject::removeGuard(&o),把T的指针从哈希表中删除。
guarded pointer
应用:
- 当您需要存储QObject的指针时,保护指针是非常有用的,该指针由其他人拥有,因此可能在您仍然持有对它的引用时被销毁。您可以安全地测试指针的有效性。
- 我们来看个例子: 如果同时删除QLabel,label则将保留变量nullptr而不是无效地址,并且永远不会执行最后一行。
QPointer<QLabel> label = new QLabel;
label->setText("&Status:");
...
if (label)
label->show();
- 除了指针算术操作符+、-、++和–之外(这些操作符通常只用于对象数组。),QPointer可用的函数和操作符与普通指针相同
guarded pointer
的使用:
- 要创建保护指针,可以从
T *
或其他相同类型的保护指针构造或分配它们。您可以使用operator==()
和operator!=()
相互比较,或nullptr使用isNull()进行测试。您可以使用*x或x->member表示法取消引用它们。 - 保护指针将自动转换为
T *
,因此您可以自由地混合保护指针和非保护指针。这意味着如果您有一个QPointer,您可以将它传递给一个需要QWidget *
的函数。出于这个原因,将函数声明为以QPointer作为参数是没有意义的;使用普通指针即可。当您在一段时间内存储指针时,请使用QPointer。 - 请注意,该类T必须继承QObject,否则将导致编译或链接错误。
注意,Qt 5在使用QPointer时引入了一个轻微的行为变化。
- 在QWidget(或QWidget的子类)上使用QPointer时,以前QWidget析构函数将清除QPointer。
- 现在,QObject析构函数将清除QPointer(因为此时将清除QWeakPointer对象)。在QWidget析构函数销毁被跟踪小部件的子部件之前,不会清除跟踪小部件的任何qpointer。
Qt还提供了QSharedPointer,它是对引用计数的共享指针对象的实现,可用于维护对单个指针的引用的集合。
另请参见QSharedPointer,QObject
和QObjectCleanupHandler。
成员函数
QPointer::clear
[since 5.0]void QPointer::clear()
清除这个QPointer对象。
这个函数是在Qt 5.0中引入的。
参见isNull()
。
QPointer::data
T *QPointer::data() const
返回指向被保护对象的指针
QPointer::get
[since 6.0]T *QPointer::get() const
与data()相同。此函数是为STL兼容性提供的。
该功能在qt6.0中引入。
QPointer::isNull()
bool QPointer::isNull() const
如果引用对象已被销毁或没有引用对象,则返回true;否则返回false。
QPointer::swap
[since 5.6]void QPointer::swap(QPointer<T> &other)
将此QPointer的内容与其他QPointer的内容交换。这个操作非常快,而且从不失败。
这个函数是在qt5.6中引入的。
QPointer::operator T *
T *QPointer::operator T *() const
Cast操作符;实现指针语义。由于此函数,您可以将QPointer传递给需要T*的函数。
&QPointer::operator*
T &QPointer::operator*() const
解引用操作符;实现指针语义。只需像普通C++指针那样使用这个操作符。
QPointer::operator->
T *QPointer::operator->() const
重载的箭头运算符;实现指针语义。只需像普通C++指针那样使用这个操作符。
&QPointer::operator=
QPointer<T> &QPointer::operator=(T *p)
赋值运算符。这个保护指针现在将指向p指向的同一个对象。
QPointer::QPointer
QPointer::QPointer(T *p)
构造一个受保护指针,该指针指向p所指向的同一对象。
QPointer::QPointer()
构造一个值为nullptr的受保护指针。
另请参见isNull()
。
QPointer::~QPointer
QPointer::~QPointer()
销毁受保护的指针。就像普通指针一样,销毁受保护的指针也不会销毁所指向的对象。