【问题标题】:How to catch exception from member destructor如何从成员析构函数中捕获异常
【发布时间】:2016-07-09 11:29:06
【问题描述】:

我想知道是否(以及如何)可以捕获成员析构函数中抛出的异常。示例:

#include <exception>

class A
{
public:
    ~A() {
        throw std::exception("I give up!");
    }
};

class B
{
    A _a;
public:
    ~B() {
        // How to catch exceptions from member destructors?
    }
};

【问题讨论】:

  • 析构函数应该以不会失败的方式编写。如果他们可以,这是糟糕设计的标志。 How to handle a destructor failure
  • @J3soon 我知道这条规则。我在问 C++ 语法以及如何做到这一点。
  • 赶上哪里?在析构函数中还是在封闭范围内?
  • 如果你想抛出异常,你需要让你的析构函数noexcept(false)

标签: c++ destructor function-try-block


【解决方案1】:

是的,您可以使用 function-try-block:

捕获此类异常
class B
{
    A _a;
public:
    ~B() try {
        // destructor body
    }
    catch (const std::exception& e)
    {
        // do (limited) stuff
    }
};

但是,对于这样的例外情况,您真的不能做太多事情。该标准规定您不能访问B 对象的非静态数据成员或基类。

此外,您不能使异常静音。与其他函数不同,一旦析构函数(或构造函数)的 function-try-block 处理程序完成执行,异常将被隐式重新抛出。

总而言之,析构函数真的不应该抛出异常。

【讨论】:

  • 你能告诉我们最后一条语句的参考吗? This answer 认为 return 语句将禁止从析构函数上的函数尝试块的处理程序自动重新抛出。
  • Found one: "到达析构函数的函数-try-block的catch子句的末尾也会自动重新抛出当前异常,就像throw;一样,但允许使用return语句。 "
  • 由于“允许返回语句”我认为仍然模棱两可(没有明确说明该语句对防止重新抛出有效),这是我找到的another,上面写着“流到最后析构函数-try-block 会导致捕获的异常被隐式重新抛出,但显式的 return 语句将防止这种情况发生。"
【解决方案2】:

这是一个不言自明的示例,您可以做什么:

#include <stdexcept>
#include <iostream>

class A
{
public:
    ~A() noexcept(false) {
        throw std::runtime_error("I give up!");
    }
};

class B
{
    A _a;
public:
    ~B() noexcept(false) try {
        // dtor body
    }
    catch (std::exception const& e)
    {
        std::cout << "~B: " << e.what() << std::endl;
        // rethrown and you can't do anything about it
    }
};

int main()
{
    try
    {
        B b;
    }
    catch (std::exception const& e)
    {
        std::cout << "main: " << e.what() << std::endl;
    }
}

Demo

我相信,对 C++ 标准的正确引用(我使用 n3376 的副本)在 15.3 处理异常中:

15 如果控制到达 构造函数的函数尝试块的处理程序的结尾或 析构函数。

【讨论】:

    猜你喜欢
    • 2013-09-28
    • 1970-01-01
    • 1970-01-01
    • 2015-11-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-09-07
    相关资源
    最近更新 更多