Безопасность исключений
Пишите код, безопасный при исключениях
«Безопасность исключений» — бесплатный урок C++ Academy на CoddyKit. Это урок 2 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения C++ Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс C++ Academy содержит 4 уроков всего.
Что означает безопасность при исключениях
Безопасность при исключениях описывает гарантии, которые сохраняет Ваш код, если исключение возбуждается в середине операции.
Гарантия отсутствия исключений
Самый высокий уровень: операция никогда не возбуждает исключений. Деструкторы, операции обмена и перемещения должны стремиться к этому уровню и объявляться как noexcept.
Строгая гарантия
Если операция возбуждает исключение, состояние программы откатывается так, словно операция никогда не начиналась, — это семантика фиксации или отката.
Базовая гарантия
Если операция возбуждает исключение, утечки ресурсов не происходит и все инварианты сохраняются, хотя точное состояние может измениться.
Отсутствие гарантии
Самый слабый уровень: исключение может оставить программу в повреждённом состоянии или вызвать утечку ресурсов. Избегайте написания такого кода.
RAII обеспечивает базовую гарантию
Оборачивая ресурсы в объекты RAII, Вы позволяете раскрутке стека автоматически освобождать их и почти бесплатно получаете базовую гарантию.
#include <memory>
#include <stdexcept>
void process() {
auto buf = std::make_unique<int[]>(100); // freed even if throw
throw std::runtime_error("oops"); // no leak
}Копирование с обменом для строгой гарантии
Распространённый приём: выполните всю рискованную работу с копией, а затем вставьте её с помощью swap. Обмен не возбуждает исключений, поэтому изменение выполняется целиком или не выполняется вовсе.
void assign(Widget& target, const Widget& src) {
Widget tmp = src; // may throw, target untouched
using std::swap;
swap(target, tmp); // no-throw commit
}Выполняйте операции так, чтобы фиксация была последней
Выполните каждую операцию, которая может возбудить исключение, до любого необратимого изменения. После начала изменения общего состояния возможность сбоя должна быть исключена.
Остерегайтесь частичных обновлений
Обновление двух членов, при котором второй может возбудить исключение, оставляет объект в несогласованном состоянии. Подготовьте оба изменения, а затем зафиксируйте их невозбуждающими исключений шагами.
Деструкторы не должны возбуждать исключения
Если деструктор возбуждает исключение во время раскрутки стека, вызывается std::terminate. Не допускайте исключений из деструкторов, чтобы сохранять гарантии безопасности.
Выбор гарантии
По возможности стремитесь к строгой гарантии, всегда обеспечивайте как минимум базовую и помечайте действительно не возбуждающие исключений операции как noexcept.
Быстрая проверка
Проверьте, насколько хорошо Вы понимаете безопасность при исключениях.
Итоги
Вы изучили четыре уровня безопасности при исключениях: отсутствие исключений, строгую, базовую и нулевую гарантии. RAII автоматически обеспечивает базовую гарантию; копирование с обменом и фиксация в последнюю очередь дают строгую гарантию. Деструкторы и операции обмена не должны возбуждать исключения.
Часто задаваемые вопросы
Урок «Безопасность исключений» бесплатный?
Да — полный текст урока «Безопасность исключений» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс C++ Academy, подпишись на CoddyKit PRO. Курс C++ Academy содержит 4 уроков всего.
Чему я научусь в уроке «Безопасность исключений»?
Пишите код, безопасный при исключениях Ты практикуешь C++ Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.
Нужен ли мне опыт, чтобы начать C++ Academy?
Предыдущий опыт не требуется. C++ Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 2 из 4.
Сколько времени занимает урок «Безопасность исключений»?
Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.
Можно ли писать и запускать код в этом уроке C++ Academy?
Да. Каждый урок C++ Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.
Все уроки этого курса
- try, catch, throw
- Безопасность исключений
- Спецификатор noexcept
- Пользовательские типы исключений