В этой статье рассмотрим:
- Как использовать this в конструкторе класса в Qt;
- Что такое this в C++ и Qt;
- Как создать объект класса в другом классе на Qt;
- Разница между созданием объектов класса с this и без.
Этот материал является частью моих занятий по программированию с теми, кто только в начале пути.
Не является полным и исчерпывающим гайдом.
Этот материал продолжение статьи: КАК СОЗДАТЬ ОБЪЕКТ КЛАССА В ДРУГОМ КЛАССЕ НА С++.**
Вот ссылка на нее: https://dzen.ru/a/aAYMLeKVhyZf03hY
В той, предыдущей, статье мы говорили, что удаление динамически созданных объектов - это лежит на ответственности программиста.
Как вы понимаете, если существует вероятность того, что объект могут забыть удалить, значит это когда нибудь произойдет.
Конкретно в Qt - об этом позаботились следующим образом, описанном ниже. Это только в Qt так работает.
1. Qt, this и parent = nullptr
В Qt существует два способа создания объектов и разница между ними заключается в том, как объект управляет своей памятью и как он связан с родительским объектом.
Рассмотрим пример.
У нас будут три класса: `MyBigApplication`, `Students`, `Homework`.
Необходимо отметить, что все они унаследованы от `QObject`.
Как это делается, при создании класса - будет предложено унаследоваться от ряда других классов, вот так:
Выбираем QObject.
Файл .h для класса Students
Файл .cpp для класса Students
Файл .h для класса Homework
Файл .cpp для класса Homework
Файл .h для класса MyBigApplication
Файл .cpp для класса MyBigApplication
Файл main
Как можно заметить, в конструкторе класса MyBigApplication создано два объекта. А в деструкторе нет ни одного delete.
Посмотрим результат:
Объекту класса Students мы не делали delete, его деструктор и не вызвался.
Однако деструктор объекта класса Homework вызвался без нашего участия.
2. Создание без `this` (без родителя):
Students* st = new Students();
- В этом случае создается объект `Students`, не передавая в конструктор `this` (т.е не указывая родителя).
- Объект `st` не будет автоматически уничтожен при уничтожении родительского объекта.
- Вы сами должны будете управлять памятью и, в конечном итоге, вызвать `delete st;`, чтобы избежать утечки памяти.
вот так будет правильно:
Получаем:
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 — это эффективное управление памятью;
- Это безопасность кода.
Всем добра)