← Назад ко всем вопросам

Что такое exception safety

1️⃣ Как кратко ответить

Exception safety — это набор гарантий, которые предоставляет код на C++ в случае возникновения исключений. Существует три уровня: базовая гарантия (basic guarantee), строгая гарантия (strong guarantee) и гарантия отсутствия исключений (no-throw guarantee). Эти уровни определяют, как код должен себя вести, чтобы оставаться корректным и предсказуемым при возникновении исключений.

2️⃣ Подробное объяснение темы

Exception safety в C++ — это концепция, которая описывает, как код должен обрабатывать исключения, чтобы оставаться в корректном состоянии. Исключения могут возникать по разным причинам, например, из-за ошибок в логике программы, нехватки ресурсов или других непредвиденных ситуаций. Exception safety помогает разработчикам писать код, который будет устойчив к таким ситуациям.

Уровни exception safety

  1. Базовая гарантия (Basic Guarantee):

    • Обеспечивает, что даже если исключение будет выброшено, программа останется в корректном состоянии. Это означает, что не будет утечек ресурсов, и все объекты останутся в допустимом состоянии, хотя и не обязательно в том, в котором они были до возникновения исключения.
    • Пример: Если в функции выбрасывается исключение, все ресурсы, которые были выделены до этого, должны быть корректно освобождены.
  2. Строгая гарантия (Strong Guarantee):

    • Обеспечивает, что если операция не может быть завершена успешно, состояние программы не изменится. Это похоже на транзакции в базах данных: либо операция завершается успешно, либо состояние откатывается к исходному.
    • Пример: При вставке элемента в контейнер, если операция не может быть завершена, контейнер останется в прежнем состоянии.
  3. Гарантия отсутствия исключений (No-Throw Guarantee):

    • Обеспечивает, что операция никогда не выбросит исключение. Это может быть полезно в ситуациях, где исключения недопустимы, например, в деструкторах или в критических секциях кода.
    • Пример: Операции над стандартными контейнерами, такими как std::vector::size(), обычно имеют гарантию отсутствия исключений.

Пример кода

Рассмотрим пример функции, которая добавляет элемент в вектор с обеспечением строгой гарантии:

#include <vector>
#include <stdexcept>
​
class SafeVector {
public:
    void addElement(int element) {
        // Создаем временный вектор для обеспечения строгой гарантии
        std::vector<int> temp = data;
​
        // Пытаемся добавить элемент во временный вектор
        try {
            temp.push_back(element);
        } catch (const std::exception& e) {
            // Если возникает исключение, просто выходим из функции
            return;
        }
​
        // Если добавление прошло успешно, обновляем основной вектор
        data = std::move(temp);
    }
​
private:
    std::vector<int> data;
};
  • std::vector<int> temp = data; — создаем копию текущего состояния вектора. Это необходимо для обеспечения строгой гарантии: если операция не удастся, исходный вектор останется неизменным.
  • temp.push_back(element); — пытаемся добавить элемент во временный вектор. Если здесь выбрасывается исключение, оно будет поймано в блоке catch.
  • catch (const std::exception& e) — ловим исключение, если оно возникает. В этом случае просто выходим из функции, не изменяя исходный вектор.
  • data = std::move(temp); — если добавление прошло успешно, обновляем основной вектор, перемещая в него данные из временного вектора.

Зачем это нужно

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

Тема: Исключения / noexcept / Safety
Стадия: Tech

🔒 Подпишись на бусти автора и стань Алигатором, чтобы получить полный доступ к функционалу сайта и отслеживать свой прогресс!

Твои заметки