Spec-Zone.ru › Qt 5.6

Класс QScopedPointer

Класс QScopedPointer хранит указатель на динамически выделенный объект и удаляет его при уничтожении. Подробнее...

Заголовок: #include <QScopedPointer>
qmake: QT += core
С момента: Qt 4.6
Наследуется от:

QScopedArrayPointer

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

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

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

QScopedPointer(T *p = Q_NULLPTR)
~QScopedPointer()
T * data() const
bool isNull() const
void reset(T *other = Q_NULLPTR)
void swap(QScopedPointer<T, Cleanup> &other)
T * take()
operator bool() const
bool operator!() const
T & operator*() const
T * operator->() const

Подробное описание

Класс QScopedPointer хранит указатель на динамически выделенный объект и удаляет его при уничтожении.

Управление объектами, выделенными в куче, вручную сложно и подвержено ошибкам, что часто приводит к утечкам памяти и трудностям при обслуживании кода. 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);

Указатели, объявленные в forward

Классы, объявленные в forward, могут использоваться в QScopedPointer, если доступен деструктор объявленного в forward класса, когда QScopedPointer нуждается в очистке.

Конкретно это означает, что все классы, содержащие QScopedPointer, указывающие на класс, объявленный в forward, должны иметь конструкторы, деструкторы и операторы присваивания, отличные от inline:

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 = Q_NULLPTR)

Конструирует экземпляр QScopedPointer и устанавливает его указатель на p.

QScopedPointer::~QScopedPointer()

Уничтожает объект QScopedPointer. Удаляет объект, на который указывает его указатель.

T *QScopedPointer::data() const

Возвращает значение указателя, на который ссылается этот объект. QScopedPointer по-прежнему владеет объектом, на который указывает указатель.

bool QScopedPointer::isNull() const

Возвращает true если этот объект хранит указатель, который null.

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

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

void QScopedPointer::swap(QScopedPointer<T, Cleanup> &other)

Меняет местами этот указатель с other.

T *QScopedPointer::take()

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

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

QScopedPointer::operator bool() const

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

if (scopedPointer) {
    ...
}

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

bool QScopedPointer::operator!() const

Возвращает true если указатель, на который ссылается этот объект, null, иначе возвращает false.

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

T &QScopedPointer::operator*() const

Обеспечивает доступ к объекту, на который указывает указатель.

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

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

T *QScopedPointer::operator->() const

Обеспечивает доступ к объекту, на который указывает указатель.

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

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

© The Qt Company Ltd
Licensed under the GNU Free Documentation License, Version 1.3.
https://doc.qt.io/archives/qt-5.6/qscopedpointer.html

Spec-Zone.ru

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