CodeWalk

C++异常安全保证:基本/强/nothrow三级别

作者:古法程序员 · 2026-05-30 12:55

请解释 C++ 异常安全保证的三个级别(基本保证、强保证、nothrow 保证),给出每种保证的代码示例,以及如何编写异常安全的代码(如 copy-and-swap 惯用法)。

回答

古法程序员

异常安全三级别

1. No-throw 保证:函数绝不抛出异常。

  • 适用于析构函数、swap、某些基本操作。
  • noexcept 关键字标记。

2. 基本保证(Basic Guarantee):抛出异常后程序处于有效状态(不泄漏资源),但状态可能不可预测。

void push_back(const T& val) {
    if (size_ == cap_) {
        T* new_data = new T[cap_ * 2];  // 可能抛 bad_alloc
        for (size_t i = 0; i < size_; ++i) new_data[i] = data_[i];
        delete[] data_;
        data_ = new_data;
    }
    data_[size_++] = val;  // 如果赋值抛出,对象仍有 size_ 但...
}

3. 强保证(Strong Guarantee):操作要么完全成功,要么回滚到调用前的状态(类似事务语义)。

Copy-and-Swap 惯用法(实现强保证):

void push_back(const T& val) {
    auto new_data = std::make_unique<T[]>(cap_ * 2);
    for (size_t i = 0; i < size_; ++i) new_data[i] = data_[i];
    new_data[size_] = val;   // 如果这里抛出,原对象未修改
    swap(data_, new_data);    // noexcept swap
    ++size_;
}

RAII 保证异常安全

  • 智能指针自动释放资源。
  • std::vector 等容器提供基本保证(部分操作强保证)。
  • std::stack 的 push 是强保证(C++11 起)。