Czy destruktory są wywoływane po wrzuceniu C++?

Uruchomiłem przykładowy program i rzeczywiście wywoływane są destruktory dla obiektów przydzielanych przez stos, ale czy jest to zagwarantowane przez standard?

Author: Luchian Grigore, 2011-11-29

2 answers

Tak, jest to gwarantowane (pod warunkiem, że wyjątek zostanie złapany), do kolejności , w której wywoływane są destruktory:

C++11 15.2 konstruktory i destruktory [except.ctor]

1 ponieważ kontrola przechodzi z wyrażenia throw do obsługi, destruktory są wywoływane dla wszystkich automatyczne obiekty budowane od momentu wprowadzenia bloku try. Na automatyczne obiekty są niszczone w odwrotnej kolejności zakończenia z ich Budownictwo.

Ponadto, jeśli wyjątek zostanie wyrzucony podczas budowy obiektu, podobiekty częściowo zbudowanego obiektu mają gwarancję poprawnego zniszczenia:

2 obiekt o dowolnym czasie przechowywania, którego inicjalizacja lub zniszczenie jest zakończone przez wyjątek będzie miał destruktory wykonywany dla wszystkich jego w pełni zbudowanych podobiektów (z wyłączeniem wariant członków klasy związkowej), czyli dla podobiektów dla które główny konstruktor (12.6.2) zakończył realizację i niszczyciel nie rozpoczął jeszcze egzekucji. Podobnie, jeśli nie delegujący konstruktor dla obiektu zakończył wykonywanie i delegowanie konstruktora dla tego obiektu kończy się z wyjątkiem, Destruktor obiektu zostanie wywołany. Jeśli obiekt został przydzielony w new-expression, pasująca funkcja dealokacji (3.7.4.2, 5.3.4, 12.5), jeżeli istnieje, jest wezwany do uwolnienia magazynu zajmowanego przez obiekt.

Cały ten proces jest znany jako "odwijanie stosu":

3 proces wywoływania destruktorów dla obiektów automatycznych zbudowanych na ścieżce od bloku try do throw-wyrażenie nazywa się " stos rozluźniam się."Jeśli Destruktor wywołany podczas odwijania stosu wychodzi z wywołany jest wyjątek, std:: terminate (15.5.1).

Odwijanie stosu stanowi podstawę szeroko stosowanej techniki zwanej pozyskiwanie zasobów jest inicjalizacją (RAII) .

Zwróć uwagę, że odwijanie stosu nie musi być wykonywane, jeśli wyjątek nie zostanie złapany. W tym przypadku od implementacji zależy, czy odwijanie stosu zostanie wykonane. Ale bez względu na to, czy odwijanie stosu jest zakończone, czy nie, w tym przypadku masz gwarancję ostatecznego połączenia do std::terminate.

C++11 15.5.1 funkcja std::terminate () [except.Zakończ]

2 ... w sytuacji, gdy nie znaleziono pasującego Handlera, jest to implementacja-definiowana czy stack jest rozwijany przed wywołaniem std::terminate().

 53
Author: NPE,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-11-29 16:41:52

Tak, destruktory mogą być wywołane przy odwijaniu stosu, w tym odwijaniu z powodu wyrzucania WYJĄTKÓW. Jest tylko kilka sztuczek z wyjątkami, które musisz pamiętać:

  • Destruktor klasy nie jest wywoływany, jeśli wyjątek jest wrzucany do jej konstruktora.
  • wyjątek jest automatycznie ponownie wyrzucany, jeśli zostanie złapany w bloku catch listy inicjalizacji budowy.
 6
Author: ,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-11-29 13:29:19