C++异常安全保证:基本/强/nothrow三级别
请解释 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 起)。