60 votes

Les destructeurs sont-ils appelés après un throw en C++ ?

J'ai exécuté un exemple de programme et les destructeurs des objets alloués à la pile sont effectivement appelés, mais est-ce garanti par la norme ?

77voto

NPE Points 169956

Oui, c'est garanti (à condition que l'exception soit attrapée), jusqu'à l'ordre dans lequel les destructeurs sont invoqués :

C++11 15.2 Constructeurs et destructeurs [except.ctor]

1 Lorsque le contrôle passe d'une expression de lancement à un gestionnaire, les destructeurs sont invoqués pour tous les objets automatiques construits depuis l'entrée dans le bloc d'essai. objets automatiques construits depuis l'entrée du bloc try. Les objets automatiques de objets automatiques sont détruits dans l'ordre inverse de l'achèvement de leur de leur construction.

En outre, si l'exception est levée pendant la construction de l'objet, les sous-objets de l'objet partiellement construit sont garantis d'être correctement détruits :

2 Un objet de n'importe quelle durée de stockage dont l'initialisation ou la destruction est terminée par une exception, les destructeurs seront exécutés exécutés pour tous ses sous-objets entièrement construits (à l'exception des (à l'exception des variantes d'une classe de type union), c'est-à-dire pour les pour lesquels le constructeur principal (12.6.2) a terminé son exécution et le destructeur n'a pas encore commencé son exécution. De même, si le constructeur non-délégataire d'un objet a terminé son exécution et qu'un constructeur et qu'un constructeur délégué pour cet objet sort avec une exception, le destructeur de l'objet sera invoqué. Si l'objet a été alloué dans une expression nouvelle expression, la fonction de désallocation correspondante (3.7.4.2, 5.3.4, 12.5), si elle existe, est appelée pour libérer l'espace occupé par l'objet.

L'ensemble de ce processus est appelé "déroulement de la pile" :

3 Le processus d'appel des destructeurs pour les objets automatiques construits automatique construit sur le chemin d'un bloc try à une expression throw est appelé "stack déroulement de la pile". Si un destructeur appelé pendant le déroulement de la pile se termine avec une exception, std::terminate est appelé (15.5.1).

Le déroulement de la pile constitue la base de la technique largement utilisée appelée L'acquisition des ressources est l'initialisation (RAII) .

Notez que le déroulement de la pile n'est pas nécessairement effectué si l'exception n'est pas attrapée. Dans ce cas, c'est à l'implémentation de décider si le déroulement de la pile est effectué. Mais que le déroulement de la pile soit effectué ou non, dans ce cas, vous avez la garantie d'un appel final à std::terminate .

C++11 15.5.1 La fonction std::terminate() [except.terminate]

2 Dans le cas où aucun gestionnaire correspondant n'est trouvé, il est défini par l'implémentation si la pile est déroulée ou non avant que std::terminate() s'appelle.

10voto

Oui, les destructeurs sont garantis d'être appelés lors du déroulement de la pile, y compris le déroulement dû à la levée d'une exception. Il n'y a que quelques astuces avec les exceptions dont vous devez vous souvenir :

  • Le destructeur de la classe n'est pas appelé si une exception est levée dans son constructeur.
  • L'exception est automatiquement rejetée si elle est attrapée dans le bloc de capture de la liste d'initialisation de la construction.

3voto

Si un throw est attrapé, les opérations cpp se poursuivent normalement. Cela inclut les destructeurs et le saut de pile. Cependant, si l'exception n'est pas attrapée, le déblocage de la pile n'est pas garanti.

De même, un throw nu ou un throw vide ne peut pas être attrapé par mon compilateur mobile.

exemple :

#include <Jav/report.h>

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

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X