Чем больше мы используем RAII в С++, тем больше мы оказываемся с деструкторами, которые выполняют нетривиальное освобождение. Теперь освобождение (завершение, однако вы хотите называть его) может потерпеть неудачу, и в этом случае исключения - это действительно единственный способ, чтобы кто-нибудь наверху знал о нашей проблеме освобождения. Но опять же, мета-деструкторы - плохая идея из-за возможности исключений, возникающих при разворачивании стека. std::uncaught_exception()
позволяет узнать, когда это произойдет, но не намного больше, поэтому, не позволяя вам регистрировать сообщение до завершения, вы не можете много сделать, если только вы не захотите оставить свою программу в состоянии undefined, где некоторые материал освобожден/финализирован, а некоторые нет.
Один из подходов состоит в том, чтобы иметь деструкторы без броска. Но во многих случаях это просто скрывает реальную ошибку. Например, наш деструктор может закрыть некоторые связанные с RAII соединения БД в результате исключения какого-либо исключения, и эти подключения к БД могут не закрыться. Это не обязательно означает, что мы в порядке с завершением программы на этом этапе. С другой стороны, регистрация и отслеживание этих ошибок на самом деле не является решением для каждого случая; иначе мы бы не нуждались в исключениях для начала. С деструкторами без броска мы также вынуждены создавать функции reset(), которые должны быть вызваны до разрушения, но это просто побеждает всю цель RAII.
Другой подход заключается только в разрешить программе завершать, поскольку это самая предсказуемая вещь, которую вы можете сделать.
Некоторые люди предлагают исключение цепочки, так что за один раз можно обрабатывать более одной ошибки. Но я, честно говоря, никогда не видел этого в С++, и я понятия не имею, как реализовать такую вещь.
Итак, это либо RAII, либо исключения. Не так ли? Я склоняюсь к бесполезным деструкторам; главным образом потому, что он держит вещи простыми (r). Но я действительно надеюсь, что там будет лучшее решение, потому что, как я уже сказал, чем больше мы используем RAII, тем больше мы используем dtors, которые делают нетривиальные вещи.
Приложение
Я добавляю ссылки на интересные по теме статьи и обсуждения, которые я нашел:
- Throwing Destructors
- Обсуждение StackOverflow в проблемах с SEH
- Обсуждение StackOverflow метательных деструкторов (спасибо, Мартин Йорк)
- Joel on Exceptions
- SEH считается вредным
- Обработка исключений CLR, которая также затрагивает цепочку исключений
- Herb Sutter на std:: uncaught_exception и почему это не так полезно, как вы думаете
- Историческая дискуссия по этому вопросу с интересными участниками (долго!)
- Строуструп объясняет RAII
- Andrei Alexandrescu Охрана области действия