How to catch exception from member destructor

2019-04-08 22:08发布

问题:

I wonder whether (and how) it's possible to catch an exception thrown in a member destructor. Example:

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

回答1:

Yes, you can catch such an exception, using the function-try-block:

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

However, you cannot really do much with such an exception. The standard specifies that you cannot access non-static data members or base classes of the B object.

Also, you cannot silence the exception. Unlike with other functions, the exception will be re-thrown implicitly once the function-try-block handler of a destructor (or constructor) finishes execution.

All in all, destructors should really not throw exceptions.



回答2:

Here is a self-explanatory example what you can do:

#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

I believe, the right reference to the C++ standard (I use copy of n3376) is in 15.3 Handling an exception:

15 The currently handled exception is rethrown if control reaches the end of a handler of the function-try-block of a constructor or destructor.