如何从成员析构函数中捕获异常

时间:2016-03-22 14:11:31

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

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

#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?
    }
};

2 个答案:

答案 0 :(得分:7)

是的,你可以使用 function-try-block来捕获这样的异常:

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

但是,对于这样的例外,你真的无能为力。该标准指定您不能访问B对象的非静态数据成员或基类。

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

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

答案 1 :(得分: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如果控制到达,则重新抛出当前处理的异常   构造函数或函数的try-try的处理程序的结尾   析构函数。