Вызываются ли деструкторы после броска в C++?
Я запустил образец программы и действительно деструкторы для объектов, выделенных стеком, называются, но гарантируется ли это стандартом?
2 ответов
Да, это гарантировано (при условии, что исключение поймано), вплоть до приказ в котором вызываются деструкторы:
C++11 15.2 конструкторы и деструкторы [за исключением.ctor]
1 когда элемент управления переходит от выражения throw к обработчику, деструкторы вызываются для всех автоматические объекты, построенные с момента ввода блока try. Этот автоматические объекты уничтожаются в обратном порядке завершения из их строительство.
кроме того, если исключение возникает во время строительства объекта, то подобъекты частично построенного объекта гарантированно будут правильно уничтожены:
2 объект любой продолжительности хранения инициализации или уничтожение прекращается исключением, будут иметь деструкторы выполняется для всех полностью построенных подобъектов (за исключением variant члены union-like класса), то есть для подобъектов для что главный конструктор (12.6.2) завершил выполнение и деструктор еще не приступил к исполнению. Аналогично, если конструктор без делегирования для объекта завершил выполнение и делегирование конструктора для этого объекта завершается с исключением, будет вызван деструктор объекта. Если объект был выделен в new-выражение, соответствующая функция освобождения (3.7.4.2, 5.3.4, 12.5), если таковые имеются, вызывается для освобождения хранилища, занятого объект.
весь этот процесс известен как "стека":
3 процесс вызова деструкторов для автоматических объектов, построенных на пути от блока try к выражению throw называется " stack размотка."Если деструктор вызывается во время размотки стека, выходы с исключение, std::terminate называется (15.5.1).
стог разматывая формирует основу широко используемого метода вызванного ресурс Приобретение-это инициализация (RAII).
обратите внимание, что размотка стека не обязательно выполняется, если исключение не поймано. В этом случае это зависит от реализации, выполняется ли размотка стека. Но независимо от того, выполняется ли размотка стека или нет, в этом случае вам гарантирован окончательный вызов std::terminate
.
C++11 15.5.1 функция std::terminate () [кроме.прекратить]
2 ... в ситуации, когда нет соответствующего обработчика не найти, его реализация-определено ли стек перед
std::terminate()
называется.
да, деструкторы гарантированно вызываются при размотке стека, включая размотку из-за исключения. Есть только несколько трюков с исключениями, которые вы должны помнить:
- деструктор класса не вызывается, если исключение возникает в конструкторе.
- исключение автоматически повторно выбрасывается, если пойман в блоке catch списка инициализации конструкции.