首页 > 代码库 > 构造函数、析构函数抛出异常的问题

构造函数、析构函数抛出异常的问题

构造函数可以抛出异常。

 

C++标准指明析构函数不能、也不应该抛出异常。

 

 

那么如果对象在运行期间出现了异常,C++异常处理模型有责任清除那些由于出现异常所导致的已经失效了的对象(也即对象超出了它原来的作用域)并释放对象原来所分配的资源, 这就是调用这些对象的析构函数来完成释放资源的任务,所以从这个意义上说,析构函数已经变成了异常处理的一部分。

 

 

上面的论述C++异常处理模型它其实是有一个前提假设——析构函数中是不应该再有异常抛出的。试想,如果对象出了异常,现在异常处理模块为了维护系统对象数据的一致性,避免资源泄漏,有责任释放这个对象的资源,调用对象的析构函数,可现在假如析构过程又再出现异常,那么请问由谁来保证这个对象的资源释放呢?而且这新出现的异常又由谁来处理呢?不要忘记前面的一个异常目前都还没有处理结束,因此这就陷入了一个矛盾之中,或者说无限的递归嵌套之中。

 

那么当无法保证在析构函数中不发生异常时, 该怎么办?

其实还是有很好办法来解决的。那就是把异常完全封装在析构函数内部,决不让异常抛出函数之外。这是一种非常简单,也非常有效的方法。  

~ClassName()

{

  try{

      do_something();

  }

  catch(){  //这里可以什么都不做,只是保证catch块的程序抛出的异常不会被扔出析构函数之外

   }

}

3.3 析构函数中抛出异常时概括性总结

1C++中析构函数的执行不应该抛出异常;

2)假如析构函数中抛出了异常,那么你的系统将变得非常危险,也许很长时间什么错误也不会发生;但也许你的系统有时就会莫名奇妙地崩溃而退出了,而且什么迹象也没有,崩得你满地找牙也很难发现问题究竟出现在什么地方;

3)当在某一个析构函数中会有一些可能(哪怕是一点点可能)发生异常时,那么就必须要把这种可能发生的异常完全封装在析构函数内部,决不能让它抛出函数之外(这招简直是绝杀!呵呵!);

4)一定要切记上面这几条总结,析构函数中抛出异常导致程序不明原因的崩溃是许多系统的致命内伤! 

 

 

 

 

 

 

 

 

构造函数、析构函数抛出异常的问题