【问题标题】:Try Catch block in destructor在析构函数中尝试 Catch 块
【发布时间】:2015-10-07 15:32:26
【问题描述】:

在阅读 Hurb Sutter 的“More Exceptional C++”时,我偶然发现了以下代码:

// Example 19-5: Alternative right solution
//
T::Close()
{
  // ... code that could throw ...
}

T::~T() /* throw() */
{
  try
  {
    Close();
  }
  catch( ... ) { }
}

我的理解是,这不是一个好主意。因为,如果在堆栈展开过程中由于异常调用了 T 析构函数,然后 Close() 抛出异常,那么这将导致 Terminate() 被调用。

有人可以解释一下吗?提前致谢。

【问题讨论】:

  • 一定要避免有可能抛出异常的析构函数,适当的捕获和管理就好了。
  • 您可能会喜欢阅读N4152,“未捕获的异常”,投票支持 C++17。

标签: c++ exception destructor


【解决方案1】:

我的理解是,这不是一个好主意。因为,如果在堆栈展开过程中由于异常调用了 T 析构函数,然后 Close() 抛出异常,那么这将导致 Terminate() 被调用。

try-catch 块正是为了防止这种情况发生。代码:

try
{
    Close();
}
catch( ... ) { }

将捕获Close 抛出的任何异常并忽略它们。因此析构函数不会抛出任何异常,这可能导致终止函数被调用。

【讨论】:

  • 我认为 OP 的问题是 Close() 在另一个异常已经处于活动状态时抛出异常是否可以。
【解决方案2】:

Close 是否可以抛出无关紧要,除非catch 允许异常逃逸。

通常catch 子句设计为永不抛出。

事实上,没有catch 子句会引入您所描述的问题。

【讨论】:

    【解决方案3】:

    一篇关于在析构函数中捕获的有趣文章:

    https://akrzemi1.wordpress.com/2011/09/21/destructors-that-throw/

    【讨论】:

    • 为了让这个问题成为一个好的答案,您应该总结文章中与这个特定问题相关的要点。
    猜你喜欢
    • 2018-08-24
    • 1970-01-01
    • 2010-12-25
    • 1970-01-01
    • 2023-03-18
    • 2011-08-22
    • 2023-03-15
    • 1970-01-01
    相关资源
    最近更新 更多