TGViewer
C/C++ | Вопросы собесов C/C++ | Вопросы собесов @easy_c_plus · 4.19K subscribers
Post #2159 811
🤔 Когда при вызове exception не зовутся деструкторы?

В C++ деструкторы объектов вызываются автоматически при выходе из области видимости, даже если выход происходит из-за исключения. Однако есть ситуации, когда деструкторы могут не вызваться, что может привести к утечке ресурсов.

🟠Динамически выделенные объекты (`new`)
Если объект был создан с помощью new, но перед его удалением произошло исключение, деструктор не вызовется автоматически.
#include <iostream>

class A {
public:
A() { std::cout << "Конструктор A\n"; }
~A() { std::cout << "Деструктор A\n"; }
};

void func() {
A* obj = new A(); // Создаем объект динамически
throw std::runtime_error("Ошибка!"); // Исключение, объект утечет
delete obj; // Никогда не выполнится
}

int main() {
try {
func();
} catch (...) {
std::cout << "Исключение поймано\n";
}
}


Как исправить?
Использовать std::unique_ptr, который автоматически удаляет объект
#include <memory>

void func() {
std::unique_ptr<A> obj = std::make_unique<A>();
throw std::runtime_error("Ошибка!"); // Деструктор вызовется автоматически
}


🟠Локальные объекты, созданные `new` внутри `try`, но `catch` не обработал исключение
Если объект выделяется внутри try, но исключение не ловится в catch, программа завершится (std::terminate), и деструкторы не вызовутся.
void func() {
A* obj = new A();
throw std::runtime_error("Ошибка!"); // std::terminate()
delete obj;
}

int main() {
func(); // Исключение не ловится => программа аварийно завершится
}


Как исправить?
Нужно обрабатывать исключение на верхнем уровне
int main() {
try {
func();
} catch (...) {
std::cout << "Ошибка обработана\n";
}
}


🟠Исключение в конструкторе
Если исключение возникает в конструкторе, деструктор этого объекта не вызывается, но деструкторы уже созданных объектов будут вызваны.
class B {
public:
B() { std::cout << "Конструктор B\n"; }
~B() { std::cout << "Деструктор B\n"; }
};

class A {
public:
A() {
std::cout << "Конструктор A\n";
throw std::runtime_error("Ошибка в конструкторе A");
}
~A() { std::cout << "Деструктор A\n"; } // Никогда не вызовется!
};

int main() {
try {
B b;
A a; // Исключение в конструкторе A
} catch (...) {
std::cout << "Исключение обработано\n";
}
}


Вывод
Конструктор B
Конструктор A
Исключение обработано
Деструктор B


Как исправить?
- Использовать концепцию "умные указатели" (std::unique_ptr), чтобы ресурсы очищались автоматически.
- Переносить ресурсоемкие операции в отдельный метод (init()), который можно вызывать после конструктора.

🟠Исключение в деструкторе
Если деструктор объекта бросает исключение, это опасно, особенно если исключение возникло в момент обработки другого исключения.
class A {
public:
~A() {
std::cout << "Деструктор A\n";
throw std::runtime_error("Ошибка в деструкторе!"); // Ошибка
}
};

int main() {
try {
A a;
throw std::runtime_error("Основное исключение");
} catch (...) {
std::cout << "Исключение обработано\n";
}
}


Как исправить?
Деструкторы не должны выбрасывать исключения. Если исключение возможно, его следует перехватывать внутри деструктора
class A {
public:
~A() {
try {
throw std::runtime_error("Ошибка в деструкторе!");
} catch (...) {
std::cout << "Ошибка подавлена в деструкторе\n";
}
}
};


Ставь 👍 и забирай 📚 Базу знаний
More from @easy_c_plus
  1. Oct 13, 2026🤔 Как устроена хеш-таблица в unordered_map? В unordered_map используется хеш-таблица с це…
  2. Oct 13, 2026🤔 Расскажите про ключевое слово _fastcall? Это соглашение о вызове функций, используемое…
  3. Oct 13, 2026Post #2566
  4. Oct 12, 2026🤔 Какие есть уровни exception гарантий? 1. No-throw Guarantee: метод или операция не выбр…
  5. Oct 12, 2026🤔 Какая сложность поиска в set и unordered_set? Контейнеры set и unordered_set представля…
  6. Oct 11, 2026🤔 Как проверять равенство двух float? Равенство двух float проверяется с учётом допустимо…
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →