QScopedPointer类
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()
来删除指针。对于积极参与QEventLoop的QObject指针,请使用此处理程序。
您可以将自己的类作为处理程序传递,前提是它们有一个公开的静态函数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。
成员函数文档
[显式 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 *>()))" 为真时,此函数不会抛出任何异常。
[显式]
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
。
[noexcept]
bool operator!=(std::nullptr_t, const QScopedPointer<T, Cleanup> &rhs)
如果 rhs 指向一个有效(即非空)的指针,则返回 true
。
[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
。
[noexcept]
bool operator==(std::nullptr_t, const QScopedPointer<T, Cleanup> &rhs)
如果 rhs 指向 nullptr
,则返回 true
。
© 2024 Qt公司有限公司。本文档贡献的文档版权属其各自所有者。本提供的文档遵守由自由软件基金会发布的 GNU自由文档许可(FDL)版本1.3 的条款。Qt及其相应的标志是芬兰和/或其他国家的Qt公司注册商标。所有其他商标均为其各自所有者的财产。