Generally speaking, if I had to handle this situation, I'd force the destructor of B
to be noexcept(true)
. For example;
class MyObject
{
public:
MyObject() {}
~MyObject() noexcept(false) {};
};
class A
{
public:
A() {}
virtual ~A() {} // implicitly noexcept(true)
};
class B : public A
{
public:
B() : A(), _object() {}
~B() noexcept(true) {};
private:
MyObject _object;
};
This will allow the code to compile, but the down-side is that whenever destruction of _object
throws an exception (in MyObject
s destructor), std::terminate()
will be called.
That case can, however, be handled if there are some actions that can be taken to prevent the destruction of _object
throwing. These actions can be performed in the destructor of B
, making use of the fact that the destructor of B
is called before the destructors of any of B
s bases or members. In other words, modify B
s destructor in the above to
// if within definition of B
~B() noexcept(true)
{
// take actions to prevent the destructor of _object throwing
};
If there are no actions that can be taken to prevent destruction of _object
from throwing, then you'll have to live with the program terminating whenever _object
s destruction throws.
My statement above that the destructor of B
will be called before the destructor of Object
or of class A
is a consequence of two rules in the standard. Construction of an object constructs bases and members, and then the constructor of the most derived class is called. And the order of destruction for an object (sequence of destructor calls) is the reverse of the order of construction.
Personally, if I had a third-party library that provided a throwing destructor in a way that can't be prevented, I'd seriously consider either finding a different library, or rolling my own equivalent library that does not have a throwing destructor.