Назад к вопросам
Middle+
102
questionbank

Что вы знаете о гарантиях безопасности исключений?

Sobes Copilot

Получайте ответы в реальном времени

Ответ от нейросети

sobes.tech AI

Гарантии безопасности исключений определяют поведение функции в случае возникновения исключения. Выделяют четыре уровня гарантий:

  1. Базовая гарантия (Basic guarantee): Если функция выбрасывает исключение, программа остается в валидном состоянии. Ресурсы не утекают (например, память освобождается), но точное состояние объектов может быть неизвестно. Сохраняется возможность дальше работать с приложением.

    // Пример базовой гарантии
    void basic_guarantee_function(std::vector<int>& vec, int value) {
        // Могут возникнуть исключения при вставке
        vec.push_back(value); 
        // Если исключение произошло, vec может быть в непредсказуемом состоянии (частично изменено),
        // но память, выделенная для vec, будет корректно освобождена при выходе из области видимости.
    } 
    
  2. Строгая гарантия (Strong guarantee): Если функция выбрасывает исключение, состояние программы остается идентичным тому, которое было до вызова функции. Все изменения откатываются.

    // Пример строгой гарантии
    // Используем Copy-and-Swap идиому для обеспечения строгой гарантии
    class Resource {
        int* data;
        size_t size;
    public:
        Resource(size_t s) : size(s), data(new int[s]) {}
        ~Resource() { delete[] data; }
        Resource(const Resource& other) : size(other.size), data(new int[other.size]) {
            std::copy(other.data, other.data + size, data); // Может выбросить исключение
        }
        Resource& operator=(Resource other) // Передача по значению вызывает копирование
        {
            swap(*this, other); // Не выбрасывает исключений
            return *this;
        }
        friend void swap(Resource& first, Resource& second) noexcept {
            using std::swap;
            swap(first.data, second.data);
            swap(first.size, second.size);
        }
        // ... другие члены
    };
    
    void strong_guarantee_function(Resource& res, size_t new_size) {
        Resource temp(new_size); // Если здесь исключение, res не изменится
        res = temp;               // Используем перегруженный оператор =, который обеспечивает строгую гарантию
    }
    
  3. Гарантия отсутствия исключений (No-throw guarantee): Функция гарантированно не выбрасывает исключений. Такие функции помечаются спецификатором noexcept.

    // Пример отсутствия исключений
    void no_throw_function() noexcept {
        // Нет операций, которые могут выбросить исключение
        int a = 5;
        int b = 10;
        int c = a + b;
    }
    
  4. Гарантия сбоя (Failure guarantee): В контексте безопасности исключений иногда упоминается этот уровень, означающий, что функция может оставить программу в неопределенном состоянии, возможна утечка ресурсов или сбои. Это фактически отсутствие гарантий. Следует избегать такого поведения.

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

Таблица сравнения гарантий:

Гарантия Состояние при исключении Целостность данных Утечки ресурсов
Базовая Валидное, но неопределенное Не гарантируется Нет
Строгая Не изменено (как до вызова) Сохраняется Нет
Отсутствия Никогда не происходит (нет исключений) N/A N/A
Сбоя (отсутствие) Неопределенное, возможно повреждение или сбои Не гарантируется Возможно