Деструкторы и освобождение ресурсов
Автоматически освобождайте ресурсы
«Деструкторы и освобождение ресурсов» — бесплатный урок C++ Academy на CoddyKit. Это урок 2 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения C++ Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс C++ Academy содержит 4 уроков всего.
Что делает деструктор
Деструктор выполняется, когда заканчивается срок жизни объекта. Его задача — освободить всё, чем владеет объект. Он называется ~ClassName.
#include <iostream>
class File {
public:
~File() { std::cout << "closing file\n"; }
};
int main() {
File f;
} // ~File runs hereОсвобождение принадлежащей памяти
Если класс владеет памятью в куче, его деструктор должен освободить её. Это классическое место для вызова delete.
#include <iostream>
class Buffer {
int* data;
public:
Buffer(int n) : data(new int[n]) {}
~Buffer() { delete[] data; } // cleanup
};
int main() { Buffer b(10); }Деструкторы выполняются автоматически
Вам не нужно самостоятельно вызывать деструкторы объектов в стеке — компилятор вставляет вызов в конце области видимости.
Обратный порядок полей
Объекты-поля уничтожаются в обратном порядке объявления после выполнения тела деструктора.
#include <iostream>
struct A { ~A() { std::cout << "~A\n"; } };
struct B { ~B() { std::cout << "~B\n"; } };
struct C {
A a;
B b; // destroyed before a
~C() { std::cout << "~C\n"; }
};
int main() { C c; }Виртуальные деструкторы
Если Вы удаляете объект Derived через указатель на объект Base, деструктор Base должен быть virtual — иначе часть Derived не будет освобождена.
#include <iostream>
struct Base {
virtual ~Base() { std::cout << "~Base\n"; }
};
struct Derived : Base {
~Derived() override { std::cout << "~Derived\n"; }
};
int main() {
Base* p = new Derived();
delete p; // both run thanks to virtual
}Деструкторы не должны выбрасывать исключения
Выбрасывание исключения из деструктора во время раскрутки стека завершает программу. Деструкторы должны быть помечены (неявно) как noexcept и никогда не должны позволять исключениям выйти наружу.
Деструктор по умолчанию
Если Вы не напишете деструктор, компилятор создаст его самостоятельно, и он уничтожит каждое поле. Для классов, содержащих только поля RAII, это именно то, что нужно.
#include <string>
#include <vector>
struct Record {
std::string name; // self-cleaning
std::vector<int> values; // self-cleaning
}; // default destructor is enoughДеструктор, заданный по умолчанию
Напишите ~Class() = default;, чтобы явно запросить деструктор, сгенерированный компилятором. Это полезно, когда нужен виртуальный деструктор без пользовательской логики.
#include <iostream>
struct Shape {
virtual ~Shape() = default; // virtual + default
};Освобождение ресурсов, отличных от памяти
Деструкторы также закрывают файлы, освобождают блокировки и отключают сокеты, а не только освобождают память. Здесь должен освобождаться любой приобретённый ресурс.
Порядок уничтожения разных объектов
Несколько локальных объектов уничтожаются в обратном порядке создания, поэтому деструктор может безопасно использовать объекты, созданные до него.
Поручайте работу полям RAII
Если каждое поле имеет тип RAII, Вам часто вообще не нужен пользовательский деструктор. Пишите деструкторы вручную только для необладающих ресурсов.
Быстрая проверка
Проверьте, насколько хорошо Вы поняли деструкторы.
Итоги
Вы узнали, что деструкторы автоматически освобождают принадлежащие ресурсы в конце срока жизни, уничтожают поля в обратном порядке объявления, не должны выбрасывать исключения и должны быть virtual в полиморфных базовых классах. Поля RAII часто избавляют от необходимости писать пользовательские деструкторы.
Часто задаваемые вопросы
Урок «Деструкторы и освобождение ресурсов» бесплатный?
Да — полный текст урока «Деструкторы и освобождение ресурсов» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс C++ Academy, подпишись на CoddyKit PRO. Курс C++ Academy содержит 4 уроков всего.
Чему я научусь в уроке «Деструкторы и освобождение ресурсов»?
Автоматически освобождайте ресурсы Ты практикуешь C++ Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.
Нужен ли мне опыт, чтобы начать C++ Academy?
Предыдущий опыт не требуется. C++ Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 2 из 4.
Сколько времени занимает урок «Деструкторы и освобождение ресурсов»?
Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.
Можно ли писать и запускать код в этом уроке C++ Academy?
Да. Каждый урок C++ Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.
Все уроки этого курса
- Принцип RAII
- Деструкторы и освобождение ресурсов
- Правило трёх/пяти
- Защитники области видимости