...
Code Block | ||||
---|---|---|---|---|
| ||||
#include <exception>
#include <stdexcept>
class S {
bool has_error() const;
public:
~S() noexcept(false) {
// Normal processing
if (has_error() && !std::uncaught_exception()) {
throw std::logic_error("Something bad");
}
}
}; |
...
Consequently, the caught exception will inevitably escape from the SomeClass
destructor . Note that exceptions thrown from noncompliant destructors of class member objects or from base classes cannot be handled because they are because it is implicitly rethrown when control reaches the end of the function-try-block handler, which is the only way to catch such exceptions.
Code Block | ||||
---|---|---|---|---|
| ||||
#include <stdexcept> class SomeClass { class Bad { bool has_error() const; public: ~Bad() noexcept(false) { if (has_error()) { throw std::logic_error("Something bad"); } } }; Bad bad_member; public: ~SomeClass() try { // ... } catch(...) { // AttemptHandle tothe handleexception exceptions thrown from the Bad destructor. } }; |
Compliant Code Example
...
A destructor should perform the same way whether or not there is an active exception. Typically, this means that it should invoke only operations that do not throw exceptions. If necessary, a try-block may be used if the destructor must invoke an operation that may throw an exception, or it should handle all exceptions and not rethrow them (even implicitly). In this compliant solution, all exceptions are caught in the function-try-block and the exception will not be rethrown because control does not reach the end of the handler due to the explicit return
statement. This handler will catch the exception thrown by Bad::~Bad()
when bad_member
is destroyed, and it will also catch any exceptions thrown within the the compound statement of the function-try-block.
Code Block | ||||
---|---|---|---|---|
| ||||
struct#include SomeClass<stdexcept> { class SomeClass ~SomeClass(){ class Bad try { // function-try-block bool has_error() const; trypublic: { // Ordinary try-block~Bad() noexcept(false) { if // Clean up (has_error()) { } catch(...) {throw std::logic_error("Something bad"); } // Catch and} handle exceptions thrown during cleanup} bad_member; public: ~SomeClass() try { } // ... } catch(...) { // Catch and log exceptions thrown from noncompliant destructors of // destructors of member objects or base class subobjects. // NOTE: Returning from a destructor function-try-block causes // causes the caught exception to be implicitly rethrown, but an // explicit return statement will prevent that from happening. return; } }; |
Noncompliant Code Example
...