Я запустил образец программы, и действительно деструкторы для объектов, выделенных для стека, вызываются, но гарантируется ли это стандартом?
Вызывается деструкторы после броска на С++?
Ответ 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"); }
}