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

Какие гарантии безопасности ты знаешь?

Sobes Copilot

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

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

sobes.tech AI

Гарантии безопасности в C++11 и более поздних версиях делятся на три типа:

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

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

  3. Гарантия отсутствия исключений (No Except Guarantee): Функция гарантированно не выбрасывает исключений. Может завершиться успешно или аварийно (например, путем std::terminate), но не через механизм исключений C++.

Примеры:

  • Для строгой гарантии часто применяется copy-and-swap идиома:

    class MyClass {
    public:
        // ...
        void swap(MyClass& other) noexcept { // Гарантия отсутствия исключений
            using std::swap;
            swap(data_, other.data_); // Предполагаем, swap(T&) не выбрасывает
        }
    
        // Строгая гарантия
        MyClass& operator=(MyClass other) { // Передача по значению для копирования
            swap(other);
            return *this;
        }
    private:
        DataType* data_; // Пример ресурса
    };
    
  • std::vector::push_back: Обычно дает базовую гарантию при добавлении существующего объекта. Может давать строгую гарантию, если копирование/перемещение элемента не выбрасывает исключений. Переаллокация может выбрасывать исключения.

  • Функции, помеченные noexcept, должны соответствовать гарантии отсутствия исключений.

Применение:

  • При проектировании API важно ясно указать, какую гарантию предоставляет каждая функция.
  • При обработке исключений следует учитывать, какая гарантия предоставляется функциями, вызываемыми в try блоке, чтобы правильно управлять состоянием.
  • Строгая гарантия часто требует дополнительных затрат (например, временное копирование), поэтому ее используют там, где это критично.
  • Гарантия отсутствия исключений важна для низкоуровневого кода и функций, вызываемых из noexcept контекстов (например, деструкторы).