1. 异常安全的基本概念与重要性
在C++开发中,异常安全(Exception Safety)是指当程序抛出异常时,代码能够保持数据一致性和资源不泄漏的能力。这个概念最早由Tom Cargill在1994年提出,后来被Bjarne Stroustrup和David Abrahams等人进一步发展完善。
异常安全之所以重要,是因为现代C++程序很难完全避免异常的发生。即使你的代码不主动抛出异常,标准库操作(如内存分配失败)、第三方库调用、甚至硬件中断都可能触发异常。如果没有妥善处理,就会导致:
- 内存泄漏(动态分配的对象未被释放)
- 资源泄漏(文件句柄、数据库连接未关闭)
- 数据不一致(部分更新导致数据结构损坏)
- 程序状态不可预测
一个典型的反面案例是:
cpp复制void unsafeFunction() {
Resource* res = new Resource();
// 如果这里抛出异常
res->doSomething();
delete res;
}
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 异常安全的三级保证体系
David Abrahams提出了异常安全的三个级别保证,这已成为业界标准:
2.1 基本保证(Basic Guarantee)
这是最低要求,确保:
- 不发生资源泄漏
- 所有对象处于有效状态(可安全销毁)
- 程序保持逻辑一致性
示例:
cpp复制void basicGuarantee(std::vector<int>& v, int newVal) {
int* p = new int(newVal);
try {
v.push_back(*p); // 可能抛出bad_alloc
} catch(...) {
delete p; // 确保异常时内存不泄漏
throw;
}
delete p;
}
2.2 强保证(Strong Guarantee)
更强的承诺:操作要么完全成功,要么完全不改变程序状态(原子性)。常用技术包括:
- 先准备所有资源,再无异常地提交
- 使用copy-and-swap惯用法
cpp复制void strongGuarantee(std::vector<int>& v, int newVal) {
std::vector<int> tmp(v); // 先拷贝
tmp.push_back(newVal); // 修改拷贝
v.swap(tmp); // 无异常交换
}
2.3 不抛保证(Nothrow Guarantee)
最高级别保证:承诺操作绝不会抛出异常。适用于:
- 析构函数(必须不抛)
- 内存释放操作
- 简单的getter方法
cpp复制// 标
