Подтвердить что ты не робот

Вызывается деструкторы после броска на С++?

Я запустил образец программы, и действительно деструкторы для объектов, выделенных для стека, вызываются, но гарантируется ли это стандартом?

4b9b3361

Ответ 1

Да, это гарантировано (при условии, что исключение поймано), вплоть до порядка, в котором вызывается деструкторы:

С++ 11 15.2 Конструкторы и деструкторы [except.ctor]

1 Когда управление переходит из выражения throw в обработчик, деструкторы вызываются для всех автоматические объекты, созданные с момента ввода блока try. автоматические объекты уничтожаются в обратном порядке завершения их строительства.

Кроме того, если исключение выбрасывается при построении объекта, субобъекты частично построенного объекта гарантированно будут правильно уничтожены:

2 Объект любой продолжительности хранения, инициализация или уничтожение прекращается с помощью исключения, будут иметь деструкторы выполняется для всех его полностью построенных подобъектов (исключая вариантные члены однопользовательского класса), т.е. для подобъектов для который главный конструктор (12.6.2) завершил выполнение и деструктор еще не приступил к исполнению. Аналогично, если конструктор без делегирования для объекта завершил выполнение и делегирующий конструктор для этого объекта завершает исключение, объект destructor будет вызван. Если объект был выделен в новое выражение, соответствующая функция освобождения (3.7.4.2, 5.3.4, 12.5), если таковой имеется, вызывается для освобождения памяти, занимаемой объектом.

Весь этот процесс известен как "разматывание стека":

3 Процесс вызова деструкторов для построенных автоматических объектов на пути от блока try к throw-выражению называется "стек" раскручивание ". Если деструктор, вызванный во время разматывания стека, выходит с исключение, std:: terminate вызывается (15.5.1).

Развертывание стека составляет основу широко используемого метода, называемого Инициализация ресурсов (RAII).

Обратите внимание, что удаление строк не обязательно выполняется, если исключение не было обнаружено. В этом случае до реализации выполняется ли перематывание стека. Но выполняется ли перематывание стека или нет, в этом случае вам гарантирован окончательный вызов std::terminate.

С++ 11 15.5.1 Функция std:: terminate() [except.terminate]

2 & hellip; В ситуации, когда соответствующий обработчик не найден, он определяется реализацией независимо от того, разрывается ли стек до того, как вызывается std::terminate().

Ответ 2

Да, деструкторы, как гарантируется, будут вызваны на разматывание стека, включая разматывание из-за того, что выбрано исключение. Есть только несколько трюков с исключениями, которые вы должны помнить:

  • Деструктор класса не вызывается, если в его конструкторе задано исключение.
  • Исключение автоматически перебрасывается, если он попадает в блок блокировки списка инициализации конструкции.

Ответ 3

Если бросок пойман, то обычно операции cpp продолжаются. Это включает в себя деструкторы и стекирование Однако, если исключение не перехвачено, выталкивание стека не гарантируется.

Кроме того, мой мобильный компилятор не может поймать голый или пустой бросок.

пример:

#include <Jav/report.h>

int main()
{
 try { throw; }
 catch(...) { rep("I bet this is not caught"); }
 }