Spec-Zone.ru › Qt 6.0

Класс 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
Наследуется от:

QScopedArrayPointer

  • Список всех членов, включая унаследованные

Примечание: Все функции в этом классе являются реентерабельными.

Открытые функции

QScopedPointer(T *p = nullptr)
~QScopedPointer()
T * data() const
T * get() const
bool isNull() const
void reset(T *other = nullptr)
T * take()
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 намеренно не имеет конструктора копирования или оператора присваивания, таким образом, владение и время жизни чётко сообщаются.

Квалификатор const для обычного указателя 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 по-прежнему владеет объектом, на который указывает указатель.

[since 5.11] T *QScopedPointer::get() const

То же, что и data().

Эта функция была добавлена в Qt 5.11.

bool QScopedPointer::isNull() const

Возвращает true , если этот объект ссылается на nullptr.

void QScopedPointer::reset(T *other = nullptr)

Удаляет существующий объект (если есть) и устанавливает свой указатель на other. QScopedPointer теперь владеет other и удалит его в своём деструкторе.

Для очистки указателя без удаления объекта, на который он указывает (и, следовательно, принятия владения объектом), используйте take() вместо этого.

T *QScopedPointer::take()

Возвращает значение указателя, на который ссылается этот объект. Указатель этого объекта QScopedPointer будет сброшен до nullptr.

Вызывающие функции принимают владение указателем.

bool QScopedPointer::operator bool() const

Возвращает true , если содержащийся указатель не nullptr. Эта функция подходит для использования в if-constructs, например:

if (scopedPointer) {
    ...
}

См. также isNull().

bool QScopedPointer::operator!() const

Возвращает true , если этот объект ссылается на nullptr.

См. также isNull().

T &QScopedPointer::operator*() const

Предоставляет доступ к объекту указателя со scope.

Если содержащийся указатель nullptr , поведение неопределённо.

См. также isNull().

T *QScopedPointer::operator->() const

Предоставляет доступ к объекту указателя со scope.

Если содержащийся указатель 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.0/qscopedpointer.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API