C++之禁止异常信息传递到析构函数外面(10)---《More Effective C++》
来源:互联网 发布:sqlserver删除实例 编辑:程序博客网 时间:2024/06/06 12:46
C++中禁止异常传递到析构函数外面有两个原因:1)异常转递的堆栈辗转开解的过程中,防止terminate函数被调用;2)能够帮助确保析构函数总能完成我们希望它完成的动作。
C++中有两种情况下会调用析构函数:1)正常情况下删除对象,如对象超出作用域或者对象指针被显示delete掉;
2)异常传递的堆栈辗转开解(stack-unwinding)过程中,由异常处理系统删除一个对象。
在上述两种情况下,调用析构函数时候异常可能处于激活状态也可能处于未激活状态,但是编译器却无法对其进行区分,这将使得我们的程序很脆弱。如果一个异常被激活的同时,同时析构函数也抛出了异常,这时候就会非常恐怖,程序的控制权转移到析构函数的外部,C++直接会调用terminate函数,并且会理解终止程序的运行,甚至局部对象都没有被释放。
1、一个异常被激活同时析构函数抛出异常,这将导致terminate函数立即执行:
class Session{public: Session(); ~Session(); ...private: static void logCreation(Session* objAddr); static void logDestruction(Session* objAddr);};
现在我们调用logDestruction()函数:
Session::~Session(){ logDestruction(this);}
试想一下如果在调用logDestruction()函数的过程中抛出异常,同时该异常也将在析构函数中抛出,这感觉,是不是感觉爽歪歪哈~~~
当然有同学会说我们可以这样处理呀:调用try…catch…异常处理机制进行局部处理:
Session::~Session(){ try{ logDestruction(this); }catch(...){ cerr<<"ERROR at address"<<this<<".\n"; }}
但是请注意这儿针对opertor<<运算符仍旧可能导致异常被抛出,又回到原来的老问题了。。。
所以我们的推荐解决方法如下:
Session::~Session(){ try{ logDestruction(this); }catch(...){}}
如果异常被析构函数抛出而没有在函数内部被不捕获,析构函数就完全不会运行,将停在抛出异常的那个地方上。
Session::Session(){ logCreation(this); startTransaction();}Session::~Session(){ logDestruction(this); endTransaction();}
如果在这里logDestruction抛出一个异常,在session构造函数内启动的transaction就没有终止。我们也许能够通过重新调整session析构函数内的函数调用顺序来消除问题,但是如果endTransaction也抛出异常的话,我们除了使用try…catch…之外别无它法。
- C++之禁止异常信息传递到析构函数外面(10)---《More Effective C++》
- More Effective C++----(11)禁止异常信息传递到析构函数外
- More Effective C++之Item M11:禁止异常信息(exceptions)传递到析构函数外
- 《More Effective C++》读书笔记-异常
- More Effective C++----(12)理解"抛出一个异常"与"传递一个参数"或"调用一个虚函数"间的差异
- C++中理解“抛出一个异常”与“传递一个参数”或“调用一个虚函数”间的差异(11)---《More Effective C++》
- C++中的异常处理开销(13)---《More Effective C++》
- More Effective C++:通过引用捕获异常
- More Effective C++:通过引用捕获异常
- <More Effective C++>笔记--异常
- <<More Effective C++>>读书笔记3: 异常
- C++之通过引用(reference)捕获异常(12)---《More Effective C++》
- C++之setjmp和longjmp不能处理C++的异常(8)---《More Effective C++》
- C++中禁止异常信息传递到析构函数外
- C++中禁止异常信息传递到析构函数外
- C++之const对象只能调用const成员函数---补充(18)《More Effective C++》
- 《More Effective C++》学习心得(七) 构造函数私有化
- More Effective C++:避免缺省构造函数
- JAVA中常用的日期转换
- 【Hibernate】项目中session的管理方式
- Android 打开关闭键盘以及监听的工具类
- JS小福利 —— 实时更新的页面小时钟
- 深入理解Java虚拟机(第七章):虚拟机类加载机制
- C++之禁止异常信息传递到析构函数外面(10)---《More Effective C++》
- Sublime Text插件FileHeader
- 基于ZXing二维码实现(示例二)(存在问题)
- 装饰者模式
- 浅析C语言的非局部跳转:setjmp和longjmp
- 密码验证合格程序
- C/C++的随机数实现
- 【Popwindow】自定义popwindow的底部间隙问题
- HDU 5458 Stability