C++ Academy · Урок

Пользовательские типы исключений

Определяйте собственные исключения

Урок 4 из 413 шагов

«Пользовательские типы исключений» — бесплатный урок C++ Academy на CoddyKit. Это урок 4 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения C++ Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс C++ Academy содержит 4 уроков всего.

Зачем нужны пользовательские исключения

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

Наследуйте от стандартного типа исключения

Создавайте свои исключения на основе std::exception или его производного типа, чтобы они интегрировались со стандартными обработчиками и предоставляли what().

#include <exception>
#include <string>

class ConfigError : public std::exception {
    std::string msg;
public:
    explicit ConfigError(std::string m) : msg(std::move(m)) {}
    const char* what() const noexcept override { return msg.c_str(); }
};

Возбуждение и перехват

Ваш тип ведёт себя как любое другое исключение: возбудите его и перехватите по ссылке.

#include <iostream>
#include <exception>
#include <string>

class ConfigError : public std::exception {
    std::string msg;
public:
    explicit ConfigError(std::string m) : msg(std::move(m)) {}
    const char* what() const noexcept override { return msg.c_str(); }
};

int main() {
    try {
        throw ConfigError("missing key");
    } catch (const ConfigError& e) {
        std::cout << e.what() << "\n";
    }
}

Повторно используйте стандартные базовые типы

Часто можно наследоваться от std::runtime_error или std::logic_error, которые уже хранят сообщение, — это уменьшает объём шаблонного кода.

#include <stdexcept>
#include <string>

class NetworkError : public std::runtime_error {
public:
    explicit NetworkError(const std::string& m) : std::runtime_error(m) {}
};

Хранение дополнительных данных

Пользовательские исключения могут хранить такие поля, как код ошибки или некорректное значение, предоставляя обработчикам больше контекста.

#include <stdexcept>
#include <string>

class HttpError : public std::runtime_error {
public:
    int status;
    HttpError(int s, const std::string& m)
        : std::runtime_error(m), status(s) {}
};

Перехват по базовому типу

Поскольку Ваш тип производен от std::exception, универсальный обработчик всё равно перехватит его через ссылку на базовый тип.

#include <iostream>
#include <stdexcept>

class HttpError : public std::runtime_error {
public:
    int status;
    HttpError(int s, const std::string& m) : std::runtime_error(m), status(s) {}
};

int main() {
    try {
        throw HttpError(404, "not found");
    } catch (const std::exception& e) {
        std::cout << e.what() << "\n";
    }
}

Создайте иерархию исключений

Объединяйте связанные ошибки под общим базовым типом, чтобы вызывающий код мог перехватывать всё семейство или один конкретный тип.

#include <stdexcept>

struct AppError : std::runtime_error { using std::runtime_error::runtime_error; };
struct DbError  : AppError       { using AppError::AppError; };
struct AuthError: AppError       { using AppError::AppError; };

Сохраняйте what() noexcept

Переопределяйте what() как const noexcept и возвращайте стабильный буфер — метод не должен возбуждать исключения или возвращать висячий указатель.

Возбуждайте по значению

Возбуждайте объекты исключений по значению (например, throw HttpError(500, "x");). Среда выполнения управляет их хранением во время раскрутки стека.

Документируйте возбуждаемые исключения

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

Сохраняйте простоту

Большинству проектов достаточно небольшого набора типов исключений. Наследование от std::runtime_error аккуратно покрывает большинство случаев.

Быстрая проверка

Проверьте, насколько хорошо Вы понимаете пользовательские исключения.

Итоги

Вы научились определять пользовательские типы исключений, наследуясь от std::exception или std::runtime_error, хранить дополнительные данные, создавать иерархии, сохранять what() как noexcept и возбуждать исключения по значению. Набор типов должен оставаться небольшим и документированным.

Можно начать бесплатно

Изучай C++ с ИИ-репетитором — бесплатно

Пиши и запускай код прямо в браузере, получай мгновенную помощь от ИИ-репетитора 24/7 и продолжи учиться на сайте или в приложении.

Курсы
51
Уроки
203

Часто задаваемые вопросы

Урок «Пользовательские типы исключений» бесплатный?

Да — полный текст урока «Пользовательские типы исключений» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс C++ Academy, подпишись на CoddyKit PRO. Курс C++ Academy содержит 4 уроков всего.

Чему я научусь в уроке «Пользовательские типы исключений»?

Определяйте собственные исключения Ты практикуешь C++ Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.

Нужен ли мне опыт, чтобы начать C++ Academy?

Предыдущий опыт не требуется. C++ Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 4 из 4.

Сколько времени занимает урок «Пользовательские типы исключений»?

Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.

Можно ли писать и запускать код в этом уроке C++ Academy?

Да. Каждый урок C++ Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.

Все уроки этого курса

  1. try, catch, throw
  2. Безопасность исключений
  3. Спецификатор noexcept
  4. Пользовательские типы исключений
← Назад к C++ Academy