[C++再学习系列] 异常安全性
2009-08-11 20:33
295 查看
异常安全性
异常安全保证有
3
种:
(a)
基本保证:保证不会发生资源泄露,即使操作失败;但是状态可能发生改变。
(b)
强保证:事务提交
/
回滚语义
。即使操作失败也不会导致程序状态改变。
(c)
无失败保证:不允许失败发生。即绝对不会抛异常。
准则:函数应该总是支持它所能支持的最强的异常安全保证,但是前提是不能给那些并不需要该保证的调用者带来额外的开销。
准则:永远不要允许析构函数
(deconstruct)
、释放操作
(deallocation)
和
swap()
函数抛出异常,否则的话,就没法安全且可靠地进行资源清理了。这是事务编程的基本前提,没有这些保证,无法确保事务提交和回滚不会失败。
编写异常安全代码的几条建议:
1)
使用“资源获取即初始化
(RAII
,特指
C++
的构造和析构函数
)
”惯用法来管理资源的所有权。如果获取失败,就释放资源,这可以防止资源泄露,还可以防止未初始化错误。
2)
使用“先在一旁将所有的事情做完,然后再通过不抛异常的操作来提交整个任务
”的手法,避免在不确定所有操作能否成功的情况下贸然去改变对象的内部状态。这就是事务性编程,常用于保证强保证。
3)
尽量使用“单一职责的类或函数”。完成多件事情的函数是很难(无法)实现强异常保证的。比如
stack
的
pop
具有取值和出栈两功能,由于
stack
可以用于存储对象(临时变量),而对象
(
非内置类型
)
的任何操作
(
对外接口或运算重载
)
都是可能抛异常的
,要实现异常安全非常困难。
参考书:Exceptional C++, Exceptional C++ Style
异常安全保证有
3
种:
(a)
基本保证:保证不会发生资源泄露,即使操作失败;但是状态可能发生改变。
(b)
强保证:事务提交
/
回滚语义
。即使操作失败也不会导致程序状态改变。
(c)
无失败保证:不允许失败发生。即绝对不会抛异常。
准则:函数应该总是支持它所能支持的最强的异常安全保证,但是前提是不能给那些并不需要该保证的调用者带来额外的开销。
准则:永远不要允许析构函数
(deconstruct)
、释放操作
(deallocation)
和
swap()
函数抛出异常,否则的话,就没法安全且可靠地进行资源清理了。这是事务编程的基本前提,没有这些保证,无法确保事务提交和回滚不会失败。
编写异常安全代码的几条建议:
1)
使用“资源获取即初始化
(RAII
,特指
C++
的构造和析构函数
)
”惯用法来管理资源的所有权。如果获取失败,就释放资源,这可以防止资源泄露,还可以防止未初始化错误。
2)
使用“先在一旁将所有的事情做完,然后再通过不抛异常的操作来提交整个任务
”的手法,避免在不确定所有操作能否成功的情况下贸然去改变对象的内部状态。这就是事务性编程,常用于保证强保证。
3)
尽量使用“单一职责的类或函数”。完成多件事情的函数是很难(无法)实现强异常保证的。比如
stack
的
pop
具有取值和出栈两功能,由于
stack
可以用于存储对象(临时变量),而对象
(
非内置类型
)
的任何操作
(
对外接口或运算重载
)
都是可能抛异常的
,要实现异常安全非常困难。
参考书:Exceptional C++, Exceptional C++ Style
相关文章推荐
- C++学习总结系列--异常处理
- [C++再学习系列] typename和依赖类型
- C++简单学习(Part3_lecture 10)(文件、流、异常处理、动态内存、命名空间)
- Spring.Net学习系列一: 统一异常处理
- [学习笔记]C++中的异常机制
- iOS 9学习系列:如何使用ATS提高应用的安全性
- [C++再学习系列] STL容器的存储结构
- sql数据库学习系列五之SQL Server 事务、异常和游标
- C++ 学习系列之 容器(一)map
- C++的异常安全性
- C++再学习系列:使用合理的引用参数实现接口的自说明
- [C++再学习系列] 具有链接的C++实体
- c++学习之异常处理简单用法
- [C++再学习系列] 跨编译单元的对象初始化
- c++学习总结系列--开始(复习)
- [C++再学习系列] 深入new/delete:类域的operator new重载
- 【面向对象语言系列】关于C++深度学习,你需要知道的事
- c++学习总结系列--序言
- [C++再学习系列] 析构函数不能失败的理由
- C++学习总结系列--拷贝构造函数