✅ 一、什么是异常安全?
异常安全是指:程序在发生异常时,能否保持正确的行为,尤其是在资源管理过程中:
不泄露资源(比如内存、文件句柄)
不破坏对象的状态
要么操作成功,要么对象状态不变(强异常安全)
“程序在发生异常时,保证对象状态合法、资源不泄漏、逻辑不乱套” —— 这就是异常安全。
✅ 二、C++ 中的异常安全级别(标准分法)
C++ 有三种常见的异常安全级别:
级别 名称 保证内容 示例
✅ 1 基本保证 不泄漏资源,对象保持合法状态 push_back() 失败,但 vector 不崩溃
✅ 2 强保证 要么操作成功,要么对象状态完全不变 类似事务操作
✅ 3 无异常保证(nothrow guarantee) 永远不会抛异常 swap()、析构函数通常应做到
三、怎么保证异常安全
✅ 方式 1:操作成功前不要修改原始数据
void transfer(Account& from, Account& to, int amount) {
Account backupFrom = from;
Account backupTo = to;
backupFrom.withdraw(amount);
backupTo.deposit(amount);
from = backupFrom;
to = backupTo;
}
✅ 方式 2:用智能指针管理资源,自动释放
template<typename T>
class MyVector {
T* data;
size_t sz;
size_t cap;
public:
void push_back(const T& value) {
if (sz == cap) {
// 扩容时可能抛异常
size_t new_cap = cap * 2 + 1;
std::unique_ptr<T[]> new_data(new T[new_cap]); // 自动管理
for (size_t i = 0; i < sz; ++i) {
new_data[i] = data[i]; // 这里如果抛异常,也不会泄漏
}
new_data[sz] = value;
// 所有成功后,才替换原数据
delete[] data;
data = new_data.release();
cap = new_cap;
} else {
data[sz] = value;
}
++sz;
}
};
四、常见方式实现异常安全
方法 原理
RAII(资源获取即初始化) 构造时获取资源,析构时释放资源,避免手动 delete
智能指针(unique_ptr, shared_ptr) 自动释放动态内存
使用标准容器 它们已经是异常安全的
swap 技术 修改临时对象,成功后替换原对象
避免手动 new/delete 自己写容易出错,建议封装在类中
构造函数抛异常时,使用智能指针清理资源 防止内存泄漏