Middle+
58
questionbank

Когда при вызове исключения (exception) не вызываются деструкторы?

Получайте ответы на вопросы в реальном времени с Sobes Copilot
Ответ от нейросети sobes.tech

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

Также деструкторы не вызываются для:

  • Объектов с глобальным или статическим временем жизни.
  • Объектов в сырой памяти, которые не управляются стандартными механизмами (например, выделены через malloc и не были освобождены).
  • Объектов, на которые указывают утекающие умные указатели.
  • Объектов, чьи деструкторы помечены как noexcept(false) и сами бросают исключение во время раскрутки стека (stack unwinding). В этом случае программа обычно аварийно завершается (std::terminate).

Пример невызова деструктора в конструкторе:

cpp

В этом примере деструктор MyClass не вызывается, поскольку конструктор MyClass не завершился успешно. Однако, деструктор res1 (подчлена MyClass) будет вызван, так как res1 был успешно сконструирован до того, как было брошено исключение.

Пример невызова деструктора при повторном исключении:

cpp

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