avatar
Грокаем C++
@grokaemcpp
14.07.2026 09:00
​​Зачем нужен деструктор?
#новичкам

На самом деле даже разработчики с опытом не всегда правильно отвечают на вопрос. Потому что все эти конструкторы и деструкторы крутятся вокруг ресурсов. Но вот каких именно? Давайте разбираться.

Несколько раз слышал ответ: "освобождает память, занятую объектом".

Следом идет вопрос: - "То есть деструктор деаллоцирует память, на месте которой находится объект?". После положительного ответа я привожу пару примеров:

void foo() {
std::vector<int> vec = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
std::cout << vec.empty();
}


Когда в этом случае вызывается деструктор и когда и как происходит деаллокация памяти, занимаемой vec?

И еще:

void foo() {
using ArrType = std::array<int, 5>;
auto * ptr = new ArrType{0, 1, 2, 3, 4};
ptr->~ArrType();
}


Происходит ли деаллокация динамической памяти в этом случае? Что здесь делает деструктор?

На самом деле деструктор просто семантически разрушает объект. Собственно это и есть значение слова "destructor" - разрушитель.

На такие темы надо рассуждать с точки зрения лайфтайма объекта. Конструктор создает объект и начинает его время жизни(даже если он ничего не делает). Деструктор же разрушает объект и заканчивает его время жизни.

Заметьте, пока про ресурсы ни слова.

Будут ли хоть какие-то ресурсы у объекта такого класса?

struct A {
int i;
char c;
};


Нет. Хотя у него есть конструктор и деструктор. Да, тривиальные, но есть же.

Когда я делаю:

void foo() {
A obj;
}

foo();


Вызывается и конструктор, и деструктор(при выходе из скоупа функции). Аллокацию и деаллокацию памяти под obj выполняет сам код, обеспечивающий запуск функции.

Разговор о ресурсах начинается тогда, когда в логике объекта заложено обладание ими. std::vector владеет указателем на динамическую память и за счет этого может масштабировать количество элементов в рантайме.

Какой-нибудь коннекшен к базе владеет открытым сокетом, через который он может общаться с ней.

Только тогда, когда объект действительно единолично владеет каким-то ресурсом, при разрушении объекта нужно этот ресурс освободить. И это не всегда память! Файловые дескрипторы и потоки - это тоже ресурсы и будет плохо, если их не освобождать.

Вернемся к примерам из начала поста.

void foo() {
using ArrType = std::array<int, 5>; // just for explicit destructor call
auto * ptr = new ArrType{0, 1, 2, 3, 4};
ptr->~ArrType();
}


std::array - это тонкая обертка над сишным массивом. Для его работы не нужны дополнительные ресурсы: его элементы располагаются ровно там, где аллоцировали память под сам объект. Поэтому и деструктор у него ничего не делает.

В примере вообще нет деаллокаций динамической памяти, так как в нем отсутствует delete, который и занимается деаллокациями.

Теперь другой:

void foo() {
std::vector<int> vec = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
std::cout << vec.empty();
}


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

Так как вектор владеет ресурсом и следует идиоме RAII, динамическая аллокация происходит внутри конструктора, а деаллокация - внутри деструктора.

Но эти аллокации не затрагивают память самого объекта vec. Память под объект - это стековая память и ей управляет рантайм.

Итого: деструктор нужен для семантического разрушения объекта и заканчивает его время жизни. Деструктор, как приличный джентельмен. должен освободить все ресурсы, которыми объект овладел за время своей жизни. Но он никак не ответственен за деаллокацию памяти под сам объект. Этим занимается либо рантайм, либо программист(явно вызывая delete).

Understand the essence. Stay cool.

#cppcore
32
👍 9
🔥 4
7 16 2.6K

Обсуждение 7

Обсуждение не доступно в веб-версии. Чтобы написать комментарий, перейдите в приложение Telegram.

Обсудить в Telegram

Грокаем C++

9.3K
Два сеньора C++ - Владимир и Денис - отныне ваши гиды в этом дремучем мире плюсов.

По всем вопросам (+ реклама) @ninjatelegramm

Менеджер: @Spiral_Yuri
Реклама: https://telega.in/c/grokaemcpp
Мы на TGstat: https://tgstat.ru/channel/@grokaemcpp/stat
Открыть в Telegram