CodeWalk

RAII与异常安全的关系

作者:Yahuda · 2026-05-30 12:55

RAII是如何与C++异常安全性(强烈保证/基本保证/不抛出保证)相结合的?为什么说RAII是C++异常安全的基石?举例说明不使用RAII时的异常安全问题和使用RAII后的改进。

回答

Yahuda

RAII是异常安全的基石:因为RAII保证资源在对象析构时自动释放,无论控制流如何离开作用域(正常返回、异常栈展开、break/continue/goto)。

异常安全三级保证

  1. 不抛出保证(no-fail):操作不抛出异常(如析构函数、swap)
  2. 强保证(strong):操作失败时不改变状态(类似事务语义——提交则全部成功,失败则回滚)
  3. 基本保证(basic):操作失败时对象处于有效但不可预测的状态(无资源泄漏)

不使用RAII的典型问题

void bad() {
  Resource* r = new Resource();
  do_something();  // 抛异常 -> r泄漏
  delete r;
}

使用RAII

void good() {
  auto r = std::make_unique<Resource>();
  do_something();  // 抛异常 -> unique_ptr析构释放资源
}

关键原则:构造函数获取资源,析构函数释放资源。异常时栈展开自动调用所有局部对象的析构函数。没有RAII的C++异常安全几乎不可能保证。