TGStat
TGStat
Введите текст для поиска
Расширенный поиск каналов
  • flag Russian
    Язык сайта
    flag Russian flag English flag Uzbek
  • Вход на сайт
  • Каталог
    Каталог каналов и чатов Региональные подборки Тематические подборки Платные каналы Поиск каналов
    Добавить канал/чат
  • Рейтинги
    Рейтинг каналов Рейтинг чатов Рейтинг публикаций
    Рейтинги брендов и персон
  • Аналитика
  • Поиск по публикациям
  • Мониторинг Telegram
  • Продвижение
    Реклама через Яндекс Бизнес Реклама в каналах через TGStat Agency Реклама на сайте TGStat.ru
Грокаем C++

14 Jul, 12:00

Открыть в Telegram Поделиться Пожаловаться

​​Зачем нужен деструктор?
#новичкам

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

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

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

void foo() {
std::vector vec = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
std::cout ~ArrType();
}

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

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

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

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

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

struct A {
int i;
char c;
};

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

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

void foo() {
A obj;
}

foo();

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

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

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

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

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

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

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

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

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

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

2.9k 0 17 7 48
Каталог
Каталог каналов и чатов Подборки каналов Поиск каналов Добавить канал/чат
Рейтинги
Рейтинг каналов Telegram Рейтинг чатов Telegram Рейтинг публикаций Рейтинги брендов и персон
API
API статистики API поиска публикаций API Callback
Наши каналы
@TGStat @TGStat_Chat @telepulse @TGStatAPI
Почитать
Академия TGStat Исследование Telegram 2019 Исследование Telegram 2021 Исследование Telegram 2023
Контакты
Справочный центр Поддержка Почта Вакансии
Всякая всячина
Пользовательское соглашение Политика конфиденциальности Публичная оферта
Наши боты
@TGStat_Bot @SearcheeBot @TGAlertsBot @tg_analytics_bot @TGStatChatBot