Ответ
Гарантии безопасности исключений (exception safety) — это свойства функции или метода, описывающие, как её поведение влияет на состояние программы при возникновении исключения. Выделяют три основные гарантии (от слабой к сильной):
-
Базовая гарантия (Basic Guarantee): При выбросе любого исключения программа остаётся в валидном состоянии. Не происходит утечек ресурсов, инварианты объектов сохраняются, но состояние может измениться (например, объект может остаться в каком-то промежуточном, но корректном состоянии).
-
Строгая гарантия (Strong Guarantee): Операция обладает транзакционной семантикой. Если операция завершается исключением, состояние программы остаётся точно таким же, как и до её начала. Это часто реализуется через идиому "copy-and-swap".
-
Гарантия отсутствия исключений (No-throw Guarantee): Операция никогда не генерирует исключений. Это критически важно для деструкторов и функций освобождения ресурсов (например,
operator delete).
Пример реализации строгой гарантии с помощью "copy-and-swap":
class String {
char* data;
size_t size;
public:
void append(const char* str) {
// 1. Создаём копию текущего состояния
String temp(*this);
// 2. Модифицируем копию (если здесь выбросится исключение, *this не пострадает)
temp.internalAppend(str);
// 3. Атомарно меняем состояние текущего объекта на новое
swap(temp); // swap обычно noexcept
}
void swap(String& other) noexcept {
std::swap(data, other.data);
std::swap(size, other.size);
}
// ...
};
Практическое правило: Деструкторы, операции swap, move должны обеспечивать no-throw guarantee. Ключевые операции следует стремиться делать либо строго безопасными, либо, как минимум, обеспечивающими базовую гарантию.