Перейти к основному содержимому

5.06. Иерархия исключений стандартной библиотеки C++

Разработчику Архитектору

Иерархия исключений стандартной библиотеки C++

Стандартная библиотека C++ определяет небольшой набор встроенных типов исключений, все из которых находятся в заголовке <stdexcept>. Кроме того, в языке допускается выбрасывать любые типы (включая примитивы, строки, пользовательские объекты), но для совместимости и читаемости рекомендуется использовать только типы, производные от std::exception.


Иерархия исключений стандартной библиотеки C++ (C++20 / C++23)

Все стандартные исключения наследуются от std::exception (заголовок <exception>).

Корневой класс:

  • std::exception

Прямые подклассы std::exception:

  1. std::logic_error — ошибки, которые могут быть обнаружены до выполнения (логические ошибки):

    • std::domain_error
    • std::invalid_argument
    • std::length_error
    • std::out_of_range
  2. std::runtime_error — ошибки, возникающие во время выполнения и зависящие от условий среды:

    • std::range_error
    • std::overflow_error
    • std::underflow_error
    • std::regex_error (C++11+)
    • std::system_error (C++11+) — используется для ошибок системного уровня (например, при работе с потоками, файлами, сокетами). Содержит код ошибки (std::error_code).
      • Некоторые реализации могут порождать std::ios_base::failure как подкласс std::system_error (начиная с C++11).
  3. std::bad_alloc — ошибка выделения памяти (new не смог выделить память). Наследуется напрямую от std::exception.

  4. std::bad_cast — ошибка при неверном использовании dynamic_cast (заголовок <typeinfo>).

  5. std::bad_typeid — ошибка при использовании typeid с нулевым указателем на полиморфный объект.

  6. std::bad_function_call (C++11+) — выбрасывается при вызове пустого std::function.

  7. std::bad_weak_ptr (C++11+) — выбрасывается при создании shared_ptr из пустого weak_ptr.

  8. std::bad_variant_access (C++17+) — выбрасывается при некорректном доступе к std::variant.

  9. std::bad_any_cast (C++17+, из <any>) — выбрасывается при ошибке приведения типа в std::any.

  10. std::ios_base::failure — исключение, связанное с операциями ввода-вывода. До C++11 наследовалось от std::exception, начиная с C++11 — от std::system_error.


Другие важные исключения, не входящие в стандартную иерархию:

  • Исключения, связанные с многопоточностью (C++11+):

    • std::future_error — при ошибках работы с std::future/std::promise.
  • Исключения, генерируемые реализацией:

    • Некоторые компиляторы могут генерировать дополнительные исключения (например, при переполнении стека), но это не стандартизировано.

Особенности модели исключений в C++:

  • Нет обязательной обработки: в отличие от Java, компилятор не требует перехвата исключений.
  • Произвольные типы: можно писать throw 42; или throw "error";, но это считается плохой практикой.
  • Рекомендация: все исключения должны наследоваться от std::exception и переопределять виртуальную функцию .what().
  • Безопасность исключений: часть стандартной библиотеки помечена как nothrow (например, деструкторы по умолчанию), чтобы избежать двойного исключения.

Как получить список программно:

C++ не предоставляет средств интроспекции типов во время выполнения для перечисления всех исключений. Список фиксирован спецификацией языка и зависит от версии стандарта (C++98, C++11, C++17, C++20, C++23).