【问题标题】:c++: Throwing exception from a destructor [duplicate]c ++:从析构函数中抛出异常[重复]
【发布时间】:2013-04-03 19:02:48
【问题描述】:

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

【问题讨论】:

  • 预期的答案可能是:“不要这样做”。阅读此处了解更多信息:stackoverflow.com/questions/130117/…
  • 如果你的类因为抛出异常和堆栈展开而被破坏,而析构函数抛出异常,程序将立即终止。没有办法捕捉或处理这样的异常。
  • 在试图确定原因以你的方式回答。

标签: c++ exception-handling destructor


【解决方案1】:

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

因此,我并没有真正遵循您的论点:

我告诉他没有,只要处理得当。

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

【讨论】:

    【解决方案2】:

    如果您从析构函数中抛出,这意味着异常实际上正在离开析构函数。所以妥善处理部分是不可能的:你无法知道它会如何处理。

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

    【讨论】:

      【解决方案3】:

      从析构函数中抛出 没有意义。

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

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

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

      因此,即使从析构函数中抛出非常安全且定义明确,它也不会给我们带来太多好处。

      【讨论】:

        猜你喜欢
        • 2022-01-16
        • 2015-08-26
        • 2012-10-28
        • 2014-08-12
        • 2019-03-11
        • 1970-01-01
        • 2019-07-11
        相关资源
        最近更新 更多