Vous n'avez pas besoin de couvrir chaque avec des try-catchs parce qu'un try-catch peut toujours attraper des exceptions non gérées lancées dans des fonctions situées plus bas dans la pile d'appels. Ainsi, plutôt que d'avoir un try-catch pour chaque fonction, vous pouvez en avoir un au niveau logique supérieur de votre application. Par exemple, il peut y avoir une fonction SaveDocument()
une routine de haut niveau, qui appelle de nombreuses méthodes qui appellent d'autres méthodes, etc. Ces sous-méthodes n'ont pas besoin de leurs propres try-catches, car s'ils sont lancés, ils sont quand même rattrapés par SaveDocument()
de la prise.
C'est intéressant pour trois raisons : c'est pratique car vous disposez d'un seul endroit pour signaler une erreur : le fichier SaveDocument()
bloc(s) de capture. Il n'est pas nécessaire de répéter cela dans toutes les sous-méthodes, et c'est ce que vous voulez de toute façon : un seul endroit pour donner à l'utilisateur un diagnostic utile sur quelque chose qui a mal tourné.
Deuxièmement, la sauvegarde est annulée dès qu'une exception est levée. Avec chaque sous-méthode try-catching, si une exception est levée, vous entrez dans le bloc catch de cette méthode, l'exécution quitte la fonction, et elle poursuit par le biais de SaveDocument()
. Si quelque chose a déjà mal tourné, vous voulez probablement vous arrêter là.
Trois, tous vos sous-méthodes peut supposer que chaque appel aboutit . Si un appel échoue, l'exécution sautera au bloc catch et le code suivant ne sera jamais exécuté. Cela peut rendre votre code beaucoup plus propre. Par exemple, voici avec les codes d'erreur :
int ret = SaveFirstSection();
if (ret == FAILED)
{
/* some diagnostic */
return;
}
ret = SaveSecondSection();
if (ret == FAILED)
{
/* some diagnostic */
return;
}
ret = SaveThirdSection();
if (ret == FAILED)
{
/* some diagnostic */
return;
}
Voici comment cela pourrait être écrit avec des exceptions :
// these throw if failed, caught in SaveDocument's catch
SaveFirstSection();
SaveSecondSection();
SaveThirdSection();
Maintenant, ce qui se passe est beaucoup plus clair.
Notez que le code sécurisé par les exceptions peut être plus difficile à écrire d'une autre manière : vous ne voulez pas perdre de mémoire si une exception est levée. Assurez-vous de connaître RAII Les objets de la STL, les conteneurs de la STL, les pointeurs intelligents et les autres objets qui libèrent leurs ressources dans les destructeurs, puisque les objets sont toujours détruits avant les exceptions.