c ++:从析构函数中抛出异常

时间:2013-04-11 14:21:30

标签: c++ exception-handling destructor

这是一个面试问题。 我告诉他,如果堆栈展开已在进行中,程序可能会终止。除此之外,如果正确处理异常,您会看到任何问题。 只要处理得当,我就告诉他。但他对我的回答并不满意。

3 个答案:

答案 0 :(得分:3)

好吧,你无法知道是否已经存在活动异常。如果存在,如果您让另一个异常从析构函数中逃脱,程序将终止。

因此,我并不真正关注你的观点:

  

只要妥善处理,我就告诉他。

除了不让它从析构函数中逃脱之外,你怎么能“正确处理”它呢?如果我是面试官,那将是我的下一个问题。

答案 1 :(得分:0)

如果从析构函数中抛出,这意味着异常实际上是离开了析构函数。因此正确处理的部分是不可能的:您无法知道如何处理它。

还有一个微妙的问题:在许多非平凡的情况下,除非假定析构函数不抛出,否则编写异常安全的代码是不可能的(或者至少是非常昂贵的)。如果你的析构函数抛出,你的类的用户将无法用它编写好的代码。例如:不可能为容器编写一个异常安全的析构函数,除非它所包含的对象的析构函数保证不会抛出。不会调用terminate(),但容器析构函数会泄漏资源。

答案 2 :(得分:0)

从析构函数中抛出使毫无意义

关于析构函数中唯一可恢复的错误类型是关闭/刷新文件时的I / O错误(或类似的网络错误等)。但从这些条件中恢复是微不足道的。只需报告错误并继续。你不需要那个文件,你刚刚试图关闭它!由于你甚至不需要的文件中的错误,放弃你正在做的事情是浪费的。

析构函数中可能发生的所有其他类型的失败,例如无法解锁互斥锁或释放内存块,可能无法恢复,并且需要调用terminate()

另一方面,在计算过程中分配资源或未能执行某个I / O的错误都需要抛出,因为计算无法继续。但是这不应该在析构函数中发生,或者如果它发生,它应该在析构函数中处理(为什么?再次,让它传播开来没有意义,这不会阻止错误会放弃一个可以愉快继续的计算。)

因此,即使从析构函数中投掷得非常安全且定义明确,也不会给我们带来太大的影响。