Plus nous utilisons RAII en C++, plus nous nous trouvons avec les destructeurs que ne le font les non-trivial de libération de la mémoire. Maintenant, de libération de la mémoire (mise au point, cependant vous voulez l'appeler) peut échouer, dans ce cas, des exceptions sont vraiment la seule façon de laisser quelqu'un à l'étage au courant de notre problème de libération de la mémoire. Mais là encore, lancer-les destructeurs sont une mauvaise idée à cause de la possibilité de l'exception levée pendant le déroulement de pile. std::uncaught_exception()
vous permet de savoir quand cela se passe, mais pas beaucoup plus, donc, en plus de vous permettre de connecter un message avant la fin il n'y a pas beaucoup que vous pouvez faire, sauf si vous êtes prêt à quitter votre programme dans un état indéfini, où certains trucs est désalloué/finalisé et d'autres non.
Une approche est de ne pas jeter des destructeurs. Mais dans de nombreux cas, qui vient se cache une véritable erreur. Notre destructeur pourrait, par exemple, la fermeture de certains RAII-géré DB connections comme un résultat de certains exception levée, et ceux DB connexions échouent à les fermer. Cela ne veut pas nécessairement dire que nous sommes ok avec le programme de s'arrêter à ce point. D'autre part, de journalisation et de suivi de ces erreurs n'est pas vraiment une solution pour chaque cas; sinon, on n'aurait pas eu besoin d'exceptions pour commencer. Sans jeter destructeurs aussi, nous trouvons dans l'obligation de créer des "reset()" les fonctions qui sont censés être appelé avant la destruction - mais qui l'emporte sur tout le but entier de RAII.
Une autre approche consiste simplement à laisser le programme de résilier, comme c'est le plus prévisible chose que vous pouvez faire.
Certaines personnes suggèrent de chaînage des exceptions, de sorte que plus d'une erreur peuvent être traitées à la fois. Mais honnêtement, je n'ai jamais vu cela se fait en C++ et je n'ai aucune idée de comment mettre en œuvre une telle chose.
Donc c'est soit RAII ou des exceptions. N'est-ce pas? Je suis penchée vers pas-de jeter des destructeurs; principalement parce qu'il garde les choses simples(r). Mais j'espère vraiment que il y a une meilleure solution, parce que, comme je l'ai dit, plus nous utilisons RAII, plus nous nous trouvons à l'aide de dtors que ne le font les non-triviales.
Annexe
Je suis ajoutant des liens intéressants sur le sujet des articles et des discussions que j'ai trouvé:
- Jeter Les Destructeurs
- StackOverflow discussion sur les problèmes avec SEH
- StackOverflow discussion sur lancer-destructeurs (merci, Martin York)
- Joel sur les Exceptions
- SEH Considéré comme Nocif
- CLR gestion des exceptions qui touche également à l'exception de chaînage
- Herb Sutter sur std::uncaught_exception et pourquoi il n'est pas aussi utile que vous ne le pensez
- Discussion historique sur la question intéressants avec les participants (long!)
- Stroustrup expliquant RAII
- Andrei Alexandrescu du Champ d'application de la Garde