QScopedPointer Class
template <typename T, typename Cleanup = QScopedPointerDeleter<T>> class QScopedPointerQScopedPointer 类存储指向动态分配对象的指针,并在销毁时将其删除。更多
头文件: | #include <QScopedPointer> |
CMake: | find_package(Qt6 REQUIRED COMPONENTS Core) target_link_libraries(mytarget PRIVATE Qt6::Core) |
qmake: | QT += core |
继承于 |
注意:该类中的所有函数都是可重入的。
公共函数
QScopedPointer(T *p = nullptr) | |
~QScopedPointer() | |
T * | data() const |
T * | get() const |
bool | isNull() const |
void | reset(T *other = nullptr) |
bool | operator bool() const |
bool | operator!() const |
T & | operator*() const |
T * | operator->() const |
相关非成员
bool | operator!=(const QScopedPointer<T, Cleanup> &lhs, const QScopedPointer<T, Cleanup> &rhs) |
bool | operator!=(const QScopedPointer<T, Cleanup> &lhs, std::nullptr_t) |
bool | operator!=(std::nullptr_t, const QScopedPointer<T, Cleanup> &rhs) |
bool | operator==(const QScopedPointer<T, Cleanup> &lhs, const QScopedPointer<T, Cleanup> &rhs) |
bool | operator==(const QScopedPointer<T, Cleanup> &lhs, std::nullptr_t) |
bool | operator==(std::nullptr_t, const QScopedPointer<T, Cleanup> &rhs) |
详细说明
手动管理堆分配对象既困难又容易出错,常见的结果是代码泄露内存且难以维护。QScopedPointer 是一个小型实用程序类,它通过为堆分配(一般称为资源获取初始化(RAII))分配基于堆栈的内存所有权,大大简化了这一过程。
QScopedPointer 可保证在当前作用域消失时,指向的对象将被删除。
考虑一下这个函数,它负责堆分配,并有多个退出点:
void myFunction(bool useSubClass) { MyClass *p = useSubClass ? new MyClass() : new MySubClass; QIODevice *device = handsOverOwnership(); if (m_value > 3) { delete p; delete device; return; } try { process(device); } catch (...) { delete p; delete device; throw; } delete p; delete device; }
它被手动删除调用所困扰。使用 QScopedPointer 后,代码可以简化为
void myFunction(bool useSubClass) { // assuming that MyClass has a virtual destructor QScopedPointer<MyClass> p(useSubClass ? new MyClass() : new MySubClass); QScopedPointer<QIODevice> device(handsOverOwnership()); if (m_value > 3) return; process(device); }
编译器为 QScopedPointer 生成的代码与手动编写的代码相同。使用delete 的代码适合使用 QScopedPointer(如果不适合,也可以使用其他类型的智能指针,如QSharedPointer )。QScopedPointer 故意不使用复制构造函数或赋值操作符,这样就能清楚地传达所有权和生命周期。
普通 C++ 指针上的 const 限定也可以用 QScopedPointer 表示:
const QWidget *const p = new QWidget(); // is equivalent to: const QScopedPointer<const QWidget> p(new QWidget()); QWidget *const p = new QWidget(); // is equivalent to: const QScopedPointer<QWidget> p(new QWidget()); const QWidget *p = new QWidget(); // is equivalent to: QScopedPointer<const QWidget> p(new QWidget());
自定义清理处理程序
使用malloc
分配的数组和指针不得使用delete
删除。QScopedPointer 的第二个模板参数可用于自定义清理处理程序。
有以下自定义清理处理程序:
- QScopedPointerDeleter - 默认情况下,使用
delete
- QScopedPointerArrayDeleter - 使用
delete []
删除指针。对于使用new []
分配的指针,请使用此处理程序。 - QScopedPointerPodDeleter - 使用
free()
删除指针。对于使用malloc()
分配的指针,请使用此处理程序。 - QScopedPointerDeleteLater - 通过调用
deleteLater()
来删除指针。该处理程序适用于指向QObject 的指针,这些指针正在参与QEventLoop 。
您可以将自己的类作为处理程序传递,前提是这些类具有公共静态函数void cleanup(T *pointer)
。
// this QScopedPointer deletes its data using the delete[] operator: QScopedPointer<int, QScopedPointerArrayDeleter<int> > arrayPointer(new int[42]); // this QScopedPointer frees its data using free(): QScopedPointer<int, QScopedPointerPodDeleter> podPointer(reinterpret_cast<int *>(malloc(42))); // this struct calls "myCustomDeallocator" to delete the pointer struct ScopedPointerCustomDeleter { static inline void cleanup(MyCustomClass *pointer) { myCustomDeallocator(pointer); } }; // QScopedPointer using a custom deleter: QScopedPointer<MyCustomClass, ScopedPointerCustomDeleter> customPointer(new MyCustomClass);
前向声明指针
只要 QScopedPointer 需要清理时,前向声明类的析构函数可用,QScopedPointer 就可以使用前向声明的类。
具体来说,这意味着所有包含指向前向声明类的 QScopedPointer 的类都必须有非内联的构造函数、析构函数和赋值运算符:
class MyPrivateClass; // forward declare MyPrivateClass class MyClass { private: QScopedPointer<MyPrivateClass> privatePtr; // QScopedPointer to forward declared class public: MyClass(); // OK inline ~MyClass() {} // VIOLATION - Destructor must not be inline private: Q_DISABLE_COPY(MyClass) // OK - copy constructor and assignment operators // are now disabled, so the compiler won't implicitly // generate them. };
否则,编译器会输出无法析构的警告:MyPrivateClass
。
另请参见 QSharedPointer 。
成员函数文档
[explicit noexcept]
QScopedPointer::QScopedPointer(T *p = nullptr)
构造此 QScopedPointer 实例,并将其指针设置为p 。
QScopedPointer::~QScopedPointer()
销毁QScopedPointer 对象。删除其指针指向的对象。
[noexcept]
T *QScopedPointer::data() const
返回该对象引用的指针的值。QScopedPointer 仍拥有指向的对象。
[noexcept]
T *QScopedPointer::get() const
与data() 相同。
[noexcept]
bool QScopedPointer::isNull() const
如果此对象指向nullptr
,则返回true
。
[noexcept(...)]
void QScopedPointer::reset(T *other = nullptr)
删除指向的现有对象(如果有),并将其指针设置为other 。现在QScopedPointer 拥有other ,并将在其析构函数中删除它。
注: 当noexcept(Cleanup::cleanup(std::declval<T *>()))
为true
时,此函数为 noexcept。
[explicit]
bool QScopedPointer::operator bool() const
如果包含的指针不是nullptr
,则返回true
。该函数适用于if-constructs
,如:
if (scopedPointer) { ... }
另请参见 isNull().
[noexcept]
bool QScopedPointer::operator!() const
如果该对象指向nullptr
,则返回true
。
另请参阅 isNull() 。
T &QScopedPointer::operator*() const
提供对作用域指针对象的访问。
如果包含的指针是nullptr
,则行为未定义。
另请参见 isNull()。
[noexcept]
T *QScopedPointer::operator->() const
提供对作用域指针对象的访问。
如果包含的指针是nullptr
,则行为未定义。
另请参阅 isNull()。
相关非成员
[noexcept]
bool operator!=(const QScopedPointer<T, Cleanup> &lhs, const QScopedPointer<T, Cleanup> &rhs)
如果lhs 和rhs 指向不同的指针,则返回true
。
[noexcept]
bool operator!=(const QScopedPointer<T, Cleanup> &lhs, std::nullptr_t)
如果lhs 指向一个有效(即非空)指针,则返回true
。
另请参见 QScopedPointer::isNull()。
[noexcept]
bool operator!=(std::nullptr_t, const QScopedPointer<T, Cleanup> &rhs)
如果rhs 指向一个有效(即非空)指针,则返回true
。
另请参见 QScopedPointer::isNull()。
[noexcept]
bool operator==(const QScopedPointer<T, Cleanup> &lhs, const QScopedPointer<T, Cleanup> &rhs)
如果lhs 和rhs 指向同一个指针,则返回true
。
[noexcept]
bool operator==(const QScopedPointer<T, Cleanup> &lhs, std::nullptr_t)
如果lhs 指向nullptr
,则返回true
。
另请参阅 QScopedPointer::isNull() 。
[noexcept]
bool operator==(std::nullptr_t, const QScopedPointer<T, Cleanup> &rhs)
如果rhs 指向nullptr
,则返回true
。
另请参阅 QScopedPointer::isNull() 。
© 2025 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.