Статьи

Учебные материалы по языку C++ — от основ до продвинутых тем

Исключения и обработка ошибок

Страница 30 из 43 · 2026-10-25 · 1 мин чтения

Исключения и обработка ошибок

Генерация исключения

throw передаёт управление механизму обработки ошибок:

#include <stdexcept>int Divide(int a, int b) {    if (b == 0) {        throw std::invalid_argument("Деление на ноль");    }    return a / b;}

Исключение подходит для ситуации, когда функция не может выполнить заявленную операцию и обычный возвращаемый результат не выражает ошибку достаточно ясно.

try и catch

try {    std::cout << Divide(10, 0) << '\n';} catch (const std::invalid_argument& error) {    std::cerr << "Ошибка: " << error.what() << '\n';}

Перехватывай стандартные исключения по const-ссылке, чтобы не копировать объект и не срезать производный тип.

Проброс исключения

Внутри catch выражение throw; повторно выбрасывает текущее исключение. Это полезно, когда текущий уровень может выполнить очистку или логирование, но не умеет полностью обработать ошибку.

RAII и исключения

При раскрутке стека локальные объекты уничтожаются. Поэтому ресурсы нужно хранить в RAII-объектах, а не полагаться на ручной код после операции, которая может выбросить исключение.

Когда исключения не нужны

Для ожидаемых ситуаций вроде «пользователь ввёл неверную команду» часто достаточно вернуть статус или std::optional. Для результата, который может быть значением или ошибкой, в C++23 существует std::expected. Выбор зависит от стандарта проекта и принятого стиля.

Не делай так

  • Не используй пустой catch (...), который молча скрывает все ошибки.
  • Не выбрасывай исключения из деструкторов при обычном уничтожении.
  • Не используй исключения как замену нормальному ветвлению в каждой итерации.

Итог

Определи, какие ошибки ожидаемы, а какие означают невозможность выполнить операцию. Обеспечивай безопасность ресурсов с RAII и обрабатывай исключения на уровне, где есть решение для пользователя или программы.