cpp异常安全
内容简介
异常安全讨论代码在抛出异常时是否仍然保持资源不泄漏、对象状态有效、程序不进入半坏状态。
这不是“会不会用 try/catch”,而是资源管理和对象设计问题。
常见保证
| 级别 | 含义 |
|---|---|
| 无保证 | 抛异常后对象状态可能混乱 |
| 基本保证 | 不泄漏资源,对象仍有效 |
| 强保证 | 操作失败时状态回滚到调用前 |
| 不抛保证 | 操作承诺不抛异常,常用 noexcept 表达 |
RAII 的作用
#include <fstream>
#include <string>
void write_log(const std::string& text)
{
std::ofstream out("log.txt");
out << text;
}即使中途发生异常,out 离开作用域也会自动析构并释放资源。
和移动语义的关系
标准库容器在扩容时,如果元素移动构造是 noexcept,更愿意移动元素;否则可能选择拷贝,以维持异常安全。
注意事项
- 析构函数通常不应该抛异常。
- 管理资源的代码优先用 RAII。
noexcept不是性能装饰,它是接口承诺。