C++异常安全保证分为基本、强和无异常抛出三类:基本保证确保资源不泄漏且对象可安全析构;强保证要求操作完全成功或回滚至原状态;无异常抛出保证要求函数声明并实际做到绝不抛异常。

C++ 的异常安全保证,是指当代码在执行过程中抛出异常时,程序仍能保持对象状态一致、资源不泄漏、行为可预测的能力。它不是语言强制的规则,而是程序员通过设计和编码实践达成的契约,直接影响代码健壮性与可维护性。核心分为三类:基本保证、强保证和无异常抛出保证(也称不抛异常保证),各自对异常发生时的状态提出不同强度的要求。
基本异常安全保证
这是最宽松但必须满足的底线:一旦异常发生,程序不会出现资源泄漏(如内存、文件句柄未释放),所有对象仍处于“有效但可能未定义”的状态——即可以安全析构或重新赋值,但其业务语义可能已改变(比如容器 size 变小了,但内部指针没 dangling)。
- 关键做法是坚持 RAII:用栈对象管理资源(std::unique_ptr、std::fstream、锁包装器等),确保构造成功则资源被接管,析构自动释放
- 避免裸 new / delete;若必须动态分配,立即转交给智能指针
- 成员函数中若需多步修改(如先改内部指针再更新计数器),应确保中间状态即使被中断也不会破坏对象不变量
强异常安全保证
更强的承诺:操作要么完全成功,要么失败后对象状态回滚到调用前的一致状态(就像什么都没发生过)。这对用户感知更友好,尤其在事务性逻辑(如银行转账、配置更新)中至关重要。
- 常用手法是“拷贝-交换”(copy-and-swap):先在临时对象中完成所有可能抛异常的操作,确认无误后再用非抛异常的 swap 交换状态
- 要求参与 swap 的操作本身是 noexcept 的(C++11 起可通过 noexcept 声明标注)
- 注意深拷贝开销;对大对象可考虑 move-aware swap 或使用 copy-on-write 等优化策略
无异常抛出保证(noexcept guarantee)
最高级别保障:函数明确声明为 noexcept,且实际执行中绝不会向外传播异常(包括析构函数、swap、移动构造/赋值等关键操作)。这不仅是安全性要求,更是性能和契约可靠性的基础。
立即学习“C++免费学习笔记(深入)”;
- 所有 noexcept 函数内不得调用可能抛异常的函数,除非你捕获并处理掉(但此时通常不再算“无异常抛出”)
- 标准容器在移动元素时,会优先选择 noexcept 的移动操作;若移动构造/赋值不是 noexcept,vector 扩容可能退化为拷贝而非移动
- 析构函数默认是 noexcept(true);若手动实现析构函数,切勿在其中抛异常(否则程序直接 terminate)
异常安全不是靠事后加 try-catch 实现的,而是靠前期资源管理设计、接口契约约定和关键操作的 noexcept 标注来构筑的防线。写库代码或核心模块时,至少要守住基本保证;对关键业务逻辑,应主动提供强保证;而 swap、移动、析构等底层支撑操作,务必做到无异常抛出。









