Можно, но крайне не рекомендуется. Выброшенное исключение из деструктора может привести к неопределённому поведению, особенно если деструктор вызывается в процессе раскрутки стека из-за другого исключения.
cpp
Основные причины, почему не стоит выбрасывать исключения из деструкторов:
std::terminate().В C++11 и новее деструкторы по умолчанию считаются noexcept, что означает, что они не должны выбрасывать исключения. Если деструктор noexcept выбрасывает исключение, происходит немедленный вызов std::terminate(). Чтобы разрешить деструктору выбрасывать исключения, его нужно явно объявить как noexcept(false).
cpp
Вместо выбрасывания исключений из деструктора, рекомендуется использовать следующие подходы для обработки ошибок при освобождении ресурсов:
close() или release(): Предоставить отдельную функцию для явного закрытия ресурса, которая может выбрасывать исключения, и вызвать её до выхода объекта из области видимости. RAII-объекты должны гарантировать освобождение ресурсов в своих деструкторах, даже если явный вызов close() не был сделан.| Подход | Рекомендуется ли | Примечания |
|---|---|---|
| Выбрасывание исключения | Нет | Может привести к std::terminate() и неопределённому поведению. |
| Возврат кода ошибки | Да (при необходимости) | Требует явной проверки ошибки после использования объекта. |
| Логирование | Да | Полезно для отладки, но не останавливает выполнение программы. |
Функция close/release | Да | Позволяет явно обрабатывать ошибки при освобождении, деструктор безопасен. |
В целом, безопасный деструктор — это такой, который никогда не выбрасывает исключения, что является частью принципа RAII (Resource Acquisition Is Initialization).