Класс QScopedPointer
шаблон <typename T, typename Cleanup> class QScopedPointerКласс QScopedPointer хранит указатель на динамически выделенный объект и удаляет его при уничтожении. Подробнее...
| Заголовок: | #include <QScopedPointer> |
| CMake: | find_package(Qt6 COMPONENTS Core REQUIRED) 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 |
Связанные нечлены
| void | swap(QScopedPointer<T, Cleanup> &lhs, 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) |
| 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;
} Она усложнена вручную вызовами delete. С 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++ указателя также может быть выражена с помощью 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 implicitely
// generate them.
}; В противном случае компилятор выводит предупреждение о невозможности уничтожения MyPrivateClass.
См. также QSharedPointer.
Документация по функциям-членам
QScopedPointer::QScopedPointer(T *p = nullptr)
Конструирует этот экземпляр QScopedPointer и устанавливает его указатель на p.
QScopedPointer::~QScopedPointer()
Уничтожает этот объект QScopedPointer. Удаляет объект, на который указывает его указатель.
T *QScopedPointer::data() const
Возвращает значение указателя, на который ссылается этот объект. QScopedPointer всё ещё владеет объектом, на который указывает указатель.
T *QScopedPointer::get() const
То же, что и data().
Эта функция была введена в Qt 5.11.
bool QScopedPointer::isNull() const
Возвращает true если этот объект ссылается на nullptr.
void QScopedPointer::reset(T *other = nullptr)
Удаляет существующий объект, на который указывает (если таковой имеется), и устанавливает свой указатель на other. QScopedPointer теперь владеет other и удалит его в своём деструкторе.
Для очистки указателя без удаления объекта, на который он указывает (и, следовательно, взятия владения объектом), используйте take() вместо этого.
bool QScopedPointer::operator bool() const
Возвращает true если содержащийся указатель не nullptr. Эта функция подходит для использования в if-constructs, например:
if (scopedPointer) {
...
} См. также isNull().
bool QScopedPointer::operator!() const
Возвращает true если этот объект ссылается на nullptr.
См. также isNull().
T &QScopedPointer::operator*() const
Обеспечивает доступ к объекту указанного указателем.
Если содержащийся указатель nullptr, поведение не определено.
См. также isNull().
T *QScopedPointer::operator->() const
Обеспечивает доступ к объекту указанного указателем.
Если содержащийся указатель nullptr, поведение не определено.
См. также isNull().
Связанные нечлены
void swap(QScopedPointer<T, Cleanup> &lhs, QScopedPointer<T, Cleanup> &rhs)
Меняет местами lhs и rhs.
bool operator!=(const QScopedPointer<T, Cleanup> &lhs, const QScopedPointer<T, Cleanup> &rhs)
Возвращает true , если lhs и rhs ссылаются на разные указатели.
[since 5.8] bool operator!=(const QScopedPointer<T, Cleanup> &lhs, std::nullptr_t)
Возвращает true , если lhs ссылается на действительный (т.е. не нулевой) указатель.
Эта функция была добавлена в Qt 5.8.
См. также QScopedPointer::isNull().
[since 5.8] bool operator!=(std::nullptr_t, const QScopedPointer<T, Cleanup> &rhs)
Возвращает true , если rhs ссылается на действительный (т.е. не нулевой) указатель.
Эта функция была добавлена в Qt 5.8.
См. также QScopedPointer::isNull().
bool operator==(const QScopedPointer<T, Cleanup> &lhs, const QScopedPointer<T, Cleanup> &rhs)
Возвращает true , если lhs и rhs ссылаются на один и тот же указатель.
[since 5.8] bool operator==(const QScopedPointer<T, Cleanup> &lhs, std::nullptr_t)
Возвращает true , если lhs ссылается на nullptr.
Эта функция была добавлена в Qt 5.8.
См. также QScopedPointer::isNull().
[since 5.8] bool operator==(std::nullptr_t, const QScopedPointer<T, Cleanup> &rhs)
Возвращает true , если rhs ссылается на nullptr.
Эта функция была добавлена в Qt 5.8.
См. также QScopedPointer::isNull().
© The Qt Company Ltd
Licensed under the GNU Free Documentation License, Version 1.3.
https://doc.qt.io/qt-6.1/qscopedpointer.html