1.构造函数异常
C++中构造函数是一个与类同名,没有返回值的特殊函数,主要是构造对象,为对象分配资源,由于没有返回值,如何判断构造对象的过程一定成功呢?
答:参考链接C++构造函数中抛出的异常
- C++中通知对象构造失败的唯一方法只能是在构造函数中抛出异常,采用throw语句来实现
- 构造函数中抛出异常将导致对象的析构函数不被执行(因构造未完成,当然不会构造,对于通过设置变量来表示构造失败,并不能阻止构造函数的执行,所以最后仍然会调用析构函数)
- 当对象发生部分构造,已经构造完成的子对象将逆序地被析构。
2.析构函数异常(参考构造函数、析构函数抛出异常的问题)
C++标准规定析构函数不能、也不应该抛出异常,从某种意义上讲,析构函数是C++异常处理机制的一部分,但析构并不是说不会发生异常
2.1 more effective c++提出两点理由(析构函数不能抛出异常的理由):
1)如果析构函数抛出异常,则异常点之后的程序不会执行,如果析构函数在异常点之后执行了某些必要的动作比如释放某些资源,则这些动作不会执行,会造成资源泄漏等问题。
2)通常异常发生时,c++的机制会调用已经构造对象的析构函数来释放资源,此时若析构函数本身也抛出异常,则前一个异常尚未处理,又有新的异常,会造成程序崩溃。
2.2 那么当无法保证在析构函数中不发生异常时, 该怎么办?
其实还是有很好办法来解决的。那就是把异常完全封装在析构函数内部,决不让异常抛出函数之外。这是一种非常简单,也非常有效的方法。
~ClassName()
{
try{
do_something();
}
catch(){ //这里可以什么都不做,只是保证catch块的程序抛出的异常不会被扔出析构函数之外。
}
}
2.3 析构函数中抛出异常时概括性总结
1)C++中析构函数的执行不应该抛出异常;
2)假如析构函数中抛出了异常,那么你的系统将变得非常危险,也许很长时间什么错误也不会发生;但也许你的系统有时就会莫名奇妙地崩溃而退出了,而且什么迹象也没有,崩得你满地找牙也很难发现问题究竟出现在什么地方;
3)当在某一个析构函数中会有一些可能(哪怕是一点点可能)发生异常时,那么就必须要把这种可能发生的异常完全封装在析构函数内部,决不能让它抛出函数之外;