Перейти к содержанию

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

Начало урока

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

Сообщайте о сбоях аккуратно, восстанавливайтесь безопасно и держите объекты в согласованном состоянии

Главная идея: исключение - это способ сообщить, что функция не смогла выполнить свою работу, и передать проблему коду, который готов её решить. Вместо возврата особого значения, которое вызывающий может проигнорировать, вы делаете throw объекта-ошибки; затем язык разматывает стек, пока не найдётся подходящий catch. Если сделать это правильно, основной ("счастливый") путь кода остаётся чистым, а ресурсы освобождаются даже при сбое.
К концу темы вы сможете:
  • правильно использовать throw, try и catch и бросать объекты, производные от std::exception,
  • объяснить разматывание стека и почему именно RAII делает исключения безопасными,
  • рассуждать о трёх гарантиях безопасности исключений (базовая, строгая, без исключений) и помечать код noexcept,
  • решать, когда использовать исключения, а когда предпочесть коды ошибок, такие как std::optional или std::error_code.

1. Почему не просто возвращать код ошибки?

Любая нетривиальная функция может дать сбой: файл не открывается, кончается память, ввод пользователя бессмыслен, чтение из сети завершается по тайм-ауту. Сообщить об этом вызывающему можно двумя основными способами.

  • Коды ошибок / особые значения: функция возвращает специальное значение (-1, nullptr, false, enum), которое вызывающий обязан проверить.
  • Исключения: функция делает throw объекта; обычное выполнение останавливается, и управление переходит к обработчику.

Беда кодов ошибок в том, что их легко проигнорировать. Ничто не заставляет вызывающего смотреть на возвращаемое значение, поэтому забытая проверка тихо портит программу. Ещё они засоряют каждое место вызова проверками if и не могут сообщить о сбое там, где нет канала возврата, - например, из конструктора или из перегруженного оператора. Исключения решают это: необработанное исключение нельзя тихо потерять (вместо этого программа завершается), а тип ошибки несёт с собой сообщение и может нести данные.

Практическое правило прямо из C++ Core Guidelines: используйте исключения для редких ошибок, которые непосредственный вызывающий обычно не может обработать, и предпочитайте возвращаемые значения для ожидаемых и локальных сбоев. Мы уточним это в разделе 7.

Продолжите этот урок на YourAIZone

В полном уроке — объяснение целиком, разобранные примеры, частые ошибки, тесты с мгновенной проверкой и ИИ-репетитор. Начните сразу как гость или создайте аккаунт, чтобы сохранять прогресс.

В полном уроке

  • Объяснение целиком
  • Разобранные примеры
  • Частые ошибки и как их избежать
  • Тестовые вопросы: 15
  • ИИ-репетитор, который отвечает на вопросы по теме
  • Отслеживание прогресса для ученика, родителей и учителя