Найти в Дзене

Qt - создаем объект класса внутри другого класса правильно| this | parent = nullptr | Как это связано и зачем нужно?

Этот материал является частью моих занятий по программированию с теми, кто только в начале пути. Не является полным и исчерпывающим гайдом. Этот материал продолжение статьи: КАК СОЗДАТЬ ОБЪЕКТ КЛАССА В ДРУГОМ КЛАССЕ НА С++.** Вот ссылка на нее: https://dzen.ru/a/aAYMLeKVhyZf03hY В той, предыдущей, статье мы говорили, что удаление динамически созданных объектов - это лежит на ответственности программиста. Как вы понимаете, если существует вероятность того, что объект могут забыть удалить, значит это когда нибудь произойдет. Конкретно в Qt - об этом позаботились следующим образом, описанном ниже. Это только в Qt так работает. В Qt существует два способа создания объектов и разница между ними заключается в том, как объект управляет своей памятью и как он связан с родительским объектом. Рассмотрим пример. У нас будут три класса: `MyBigApplication`, `Students`, `Homework`. Необходимо отметить, что все они унаследованы от `QObject`. Как это делается, при создании класса - будет предло
Оглавление

Разбираем пример как создать объект класса внутри другого в Qt и не думать об удалении
Разбираем пример как создать объект класса внутри другого в Qt и не думать об удалении

В этой статье рассмотрим:

  • Как использовать this в конструкторе класса в Qt;
  • Что такое this в C++ и Qt;
  • Как создать объект класса в другом классе на Qt;
  • Разница между созданием объектов класса с this и без.

Этот материал является частью моих занятий по программированию с теми, кто только в начале пути.
Не является полным и исчерпывающим гайдом.

Этот материал продолжение статьи: КАК СОЗДАТЬ ОБЪЕКТ КЛАССА В ДРУГОМ КЛАССЕ НА С++.**
Вот ссылка на нее: https://dzen.ru/a/aAYMLeKVhyZf03hY

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

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

Конкретно в Qt - об этом позаботились следующим образом, описанном ниже. Это только в Qt так работает.

1. Qt, this и parent = nullptr

В Qt существует два способа создания объектов и разница между ними заключается в том, как объект управляет своей памятью и как он связан с родительским объектом.

Рассмотрим пример.

У нас будут три класса: `MyBigApplication`, `Students`, `Homework`.

Необходимо отметить, что все они унаследованы от `QObject`.

Как это делается, при создании класса - будет предложено унаследоваться от ряда других классов, вот так:

-2

Выбираем QObject.

-3

Файл .h для класса Students

-4

Файл .cpp для класса Students

-5

Файл .h для класса Homework

-6

Файл .cpp для класса Homework

-7

Файл .h для класса MyBigApplication

-8

Файл .cpp для класса MyBigApplication

-9

Файл main

-10

Как можно заметить, в конструкторе класса MyBigApplication создано два объекта. А в деструкторе нет ни одного delete.

Посмотрим результат:

-11

Объекту класса Students мы не делали delete, его деструктор и не вызвался.

Однако деструктор объекта класса Homework вызвался без нашего участия.

2. Создание без `this` (без родителя):

Students* st = new Students();

  • В этом случае создается объект `Students`, не передавая в конструктор `this` (т.е не указывая родителя).
  • Объект `st` не будет автоматически уничтожен при уничтожении родительского объекта.
  • Вы сами должны будете управлять памятью и, в конечном итоге, вызвать `delete st;`, чтобы избежать утечки памяти.
-12

вот так будет правильно:

Исправили ошибку
Исправили ошибку

Получаем:

Теперь все объекты удалены
Теперь все объекты удалены

3. Создание с родителем: Использование this в конструкторе Qt для управления памятью.

Вот пример использования this в конструкторе класса на Qt:

Homework* work = new Homework(this);

Что такое this в C++ и Qt?

  • `this` - это адрес для текущего объекта в памяти (для `MyBigApplication`).
  • Здесь передается `this` в качестве родителя, что означает, что `Homework` будет связан с текущим объектом (например, классом (MyBigApplication), в котором вы создаете `Homework`).
  • Когда родительский объект (MyBigApplication) уничтожается, все его дочерние объекты (включая `Homework`) автоматически уничтожаются. Это упрощает управление памятью и снижает риск утечек памяти.
  • Это особенно полезно в контексте GUI-приложений, где объекты часто создаются и уничтожаются в зависимости от жизненного цикла виджетов.

Если ваш класс `MyBigApplication` является виджетом или частью интерфейса, и вы создаете `Homework` с `this` в качестве родителя, вам не нужно беспокоиться о том, чтобы вручную удалять объект `work`, когда `MyBigApplication` будет уничтожен.

Использование родителя (`this` второй способ) является хорошей практикой в Qt, так как это упрощает управление памятью и предотвращает утечки.

4. explicit Students(QObject *parent = nullptr)

Давайте коротко рассмотрим что это такое.

`class Students` унаследован от `QObject`.

class Students : public QObject

  • Наследование позволяет классу `Students` использовать все функции и свойства, которые есть в `QObject`.

Зачем нам это необходимо.

  • Получим доступ к механизму сигналов и слотов. Это очень крутая концепция для общения между объектами классов.

Один класс говорит, что произошло событие, а второй реагирует и обрабатывает его своими действиями.

Получим возможность автоматического управления памятью через механизм родительских объектов (`this`).

  • `QObject *parent` - это указатель на объект типа `QObject`.

Указатель - это переменная, которая хранит адрес другого объекта в памяти.

Дак вот, мы можем передать адрес объекта `MyBigApplication` (он же `this`) в качестве родителя для `Students`.

  • Теперь когда будет удаляться в памяти родитель, все его дочерние объекты также уничтожаются.
  • `nullptr` - это специальное слово, которое говорит, что указатель не ссылается ни на какой объект.

Передали в конструктор адрес - ссылается, не передали - значит не ссылается по умолчанию и не имеет родителя, живет свой жизнью. Ответственность за его удаление несет разработчик.

Послесловие:

- Используйте `this`, если ваш класс унаследован от `QObject`;

- Понимание this в контексте Qt — это эффективное управление памятью;

- Это безопасность кода.

Ссылка на файлы с кодом

Всем добра)