В конструкторе выброс исключения приводит к тому, что объект не будет полностью сконструирован. Порядок выполнения деструкторов для полностью или частично сконструированных подобъектов определяется стандартом: деструкторы будут вызваны для всех членов и базовых классов, которые были успешно инициализированы до момента генерации исключения.
Проблема выброса исключений из деструктора заключается в следующем: если деструктор вызывается в процессе раскрутки стека из-за другого исключения, и сам выбрасывает исключение, происходит вызов std::terminate(). Это приводит к аварийному завершению программы, так как стандарт не позволяет выбрасывать новое исключение во время обработки существующего. Следовательно, выбрасывать исключения из деструкторов в общем случае крайне не рекомендуется.
Пример выброса исключения в конструкторе:
cpp
Пример, который может привести к вызову std::terminate() (иллюстративный, в реальном коде так делать не стоит):
cpp
В последнем примере, если деструктор BadDestructor выбрасывает исключение во время обработки другого исключения, программа завершится вызовом std::terminate(). Использование noexcept(false) в сигнатуре деструктора сигнализирует о возможности выброса исключения, но не решает проблему двойного исключения. Стандартная практика - делать деструкторы noexcept(true) (что является поведением по умолчанию в новых стандартах C++).