异常安全性
老样子,先放出第一手信息源
今天我们只讨论简单的异常安全
简单点说,异常安全就是保证在执行我们的函数的时候,不会出现资源的破坏,或者泄露的情况
之前讲到的RAII其实就是一种处理情况,即利用了自动析构的特性帮助我们管理资源
这里再来讲一种情况
class A {
A &operator= (const A &others) {
if (this != &others) {
delete ptr;
ptr = new T(*others.ptr);
}
return *this;
}
private:
T *ptr;
}
深拷贝,首先判断是不是自我复制,然后我们删除原本的资源,并复制一份新的资源
在这个过程中,如果我们的new抛出了异常,那么就会导致出现我们delete掉了原本的资源,但是新的资源没有获取成功的情况
这就导致了对象资源的破坏,我们可以使用一种叫做copy and swap
的策略来实现一个异常安全的版本
class A{
A &operator= (const A &others) {
A tmp(others);
using std::swap;
swap(others.ptr, ptr);
}
}
这里首先我们调用拷贝构造函数,构造了一个others的副本,然后交换副本和我们管理的资源
由于std::swap
是保证不会抛出异常的,所以即便是拷贝构造函数出了问题,也不会导致原对象的破坏
并且在函数的结尾,tmp会自动析构掉他的资源,也就是原本在我们这里管理的资源
有关的拓展可以参考这篇文章copy and swap
最后提一嘴,我们这里实现的是强异常安全,即操作可能失败,但是不会具有任何影响,原本的对象仍然是完整的
有关其他的异常安全类型,可以看这个,或者看wiki
文章评论