Как отловить исключение из члена-деструктора

Интересно, можно ли (и как) поймать исключение, выброшенное в деструкторе члена. Пример:

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

5

Решение

Да, вы можете поймать такое исключение, используя Функция-примерочных блок:

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

Тем не менее, вы не можете сделать многое с таким исключением. Стандарт определяет, что вы не можете получить доступ к нестатическим элементам данных или базовым классам B объект.

Вас также не могу молчание исключения. В отличие от других функций, исключение будет переброшено неявно, как только Функция-примерочный блок Обработчик деструктора (или конструктора) заканчивает выполнение.

В общем, деструкторы не должны бросать исключения.

6

Другие решения

Вот очевидный пример того, что вы можете сделать:

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

демонстрация

Я считаю, что правильная ссылка на стандарт C ++ (я использую копию n3376) находится в 15.3 Обработка исключения:

15 В настоящее время обработанное исключение перебрасывается, если элемент управления достигает
конец обработчика функции-try-блока конструктора или
деструктор.

2

По вопросам рекламы [email protected]