Вызываются ли деструкторы после броска в 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 списка инициализации конструкции.