Мы должны дифференцировать здесь вместо слепого следования общего совета для конкретных случаев.
Обратите внимание, что в следующем игнорируется проблема контейнеров объектов и того, что нужно делать перед лицом множества объектов в контейнерах. (И это может быть частично проигнорировано, так как некоторые объекты просто не подходят для размещения в контейнере.)
Вся проблема становится более понятной, когда мы разделяем классы на два типа. У класса dtor могут быть две разные обязанности:
- (R) освободить семантику (она же освобождает память)
- (C) принятие семантика (или сброс файла на диск)
Если мы рассмотрим вопрос таким образом, то я думаю, что можно утверждать, что (R) семантика никогда не должна вызывать исключение из dtor, поскольку есть а) мы ничего не можем с этим поделать и б) много свободных ресурсов операции даже не предусматривают проверку ошибок, например void
free(void* p);
.
Объекты с семантикой (C), такие как файловый объект, который должен успешно очистить свои данные, или (база данных, защищенная областью), которая выполняет фиксацию в dtor, имеют другой вид: Мы можем сделайте что-нибудь с ошибкой (на уровне приложения), и мы действительно не должны продолжать, как будто ничего не произошло.
Если мы следуем по маршруту RAII и учитываем объекты, которые имеют (C) семантику в своих d'-dors, я думаю, что тогда мы также должны учесть нечетный случай, когда такие d-dors могут генерировать. Из этого следует, что вы не должны помещать такие объекты в контейнеры, а также из этого следует, что программа все еще может terminate()
, если commit-dtor выдает, когда другое исключение активно.
Что касается обработки ошибок (семантика фиксации / отката) и исключений, то один хороший разговор Андрей Александреску : Обработка ошибок в C ++ / Декларативный поток управления (удерживается в НДЦ 2014 )
В деталях он объясняет, как библиотека Folly реализует UncaughtExceptionCounter
для своих инструментов ScopeGuard
.
(Я должен отметить, что другие также имели подобные идеи.)
Хотя речь не фокусируется на броске из д'тора, он показывает инструмент, который можно использовать сегодня , чтобы избавиться от проблем с тем, когда бросать из д'тор
В будущем , может быть стандартной функцией для этого, см. N3614 , и обсуждение это .
Upd '17: для C ++ 17 стандартная функция std::uncaught_exceptions
afaikt. Я быстро процитирую статью cppref:
Примечания
Примером использования int
-обращения uncaught_exceptions
является ... ... first
создает объект охраны и записывает количество необработанных исключений
в своем конструкторе. Вывод осуществляется охранником объекта
деструктор, если только foo () не сгенерирует ( в этом случае
исключения в деструкторе больше, чем в конструкторе
Наблюдаемый )