J'ai une très mauvaise compréhension de la gestion des exceptions (c'est-à-dire, comment personnaliser les instructions throw, try, catch à mes propres fins).
Par exemple, j'ai défini une fonction comme suit: int compare(int a, int b){...}
J'aimerais que la fonction lève une exception avec un message lorsque a ou b est négatif.
Comment dois-je aborder cela dans la définition de la fonction?
c++
exception-handling
Terry Li
la source
la source
unsigned int
comme paramètres dans votre signature de fonction. Là encore, je suis de l'école que vous ne devriez lever et attraper des exceptions que pour des choses qui sont réellement exceptionnelles.throw()
des spécifications d'exception sur les fonctions.Réponses:
Facile:
La bibliothèque standard est livrée avec une belle collection d' objets d'exception intégrés que vous pouvez lancer. Gardez à l'esprit que vous devez toujours lancer par valeur et attraper par référence:
Vous pouvez avoir plusieurs instructions catch () après chaque essai, vous pouvez donc gérer différents types d'exceptions séparément si vous le souhaitez.
Vous pouvez également relancer les exceptions:
Et pour intercepter les exceptions quel que soit le type:
la source
throw;
(en renvoyant l'objet d'origine et en préservant son type) plutôt qu'enthrow e;
(jetant une copie de l'objet capturé, en changeant éventuellement son type).Ajoutez simplement
throw
là où vous en avez besoin ettry
bloquez l'appelant qui gère l'erreur. Par convention, vous ne devriez jeter que les choses qui en dériventstd::exception
, donc incluez d'<stdexcept>
abord.Consultez également Boost.Exception .
la source
Bien que cette question soit assez ancienne et ait déjà reçu une réponse, je veux juste ajouter une note sur la façon de gérer correctement les exceptions en C ++ 11:
Utiliser
std::nested_exception
etstd::throw_with_nested
Il est décrit sur StackOverflow ici et ici , comment vous pouvez obtenir une trace arrière sur vos exceptions dans votre code sans avoir besoin d'un débogueur ou d'une journalisation encombrante, en écrivant simplement un gestionnaire d'exceptions approprié qui renverra les exceptions imbriquées.
Comme vous pouvez le faire avec n'importe quelle classe d'exception dérivée, vous pouvez ajouter beaucoup d'informations à une telle trace! Vous pouvez également jeter un oeil à mon MWE sur GitHub , où une trace ressemblerait à quelque chose comme ceci:
la source
Vous pouvez définir un message à lancer lorsqu'une certaine erreur se produit:
ou vous pouvez le définir comme ceci:
En règle générale, vous auriez un
try ... catch
bloc comme celui-ci:la source
Je voulais AJOUTER aux autres réponses décrites ici une note supplémentaire, dans le cas des exceptions personnalisées .
Dans le cas où vous créez votre propre exception personnalisée, qui dérive de
std::exception
, lorsque vous interceptez "tous les types d'exceptions" possibles, vous devez toujours démarrer lescatch
clauses avec le type d'exception "le plus dérivé" qui peut être intercepté. Voir l'exemple (de ce qu'il ne faut PAS faire):REMARQUE:
0) L'ordre correct doit être vice-versa, c'est-à-dire d'abord vous
catch (const MyException& e)
qui est suivi parcatch (const std::exception& e)
.1) Comme vous pouvez le voir, lorsque vous exécutez le programme tel quel, la première clause catch sera exécutée (ce qui est probablement ce que vous ne vouliez PAS en premier lieu).
2) Même si le type capturé dans la première clause catch est de type
std::exception
, la version "appropriée" dewhat()
sera appelée - car elle est capturée par référence (changez au moins lestd::exception
type d' argument capturé par valeur - et vous rencontrerez phénomènes de "tranchage d'objets" en action).3) Dans le cas où "un certain code dû au fait que l'exception XXX a été levée ..." fait des choses importantes EN CE QUI CONCERNE le type d'exception, il y a un mauvais comportement de votre code ici.
4) Ceci est également pertinent si les objets capturés étaient des objets "normaux" comme:
class Base{};
etclass Derived : public Base {}
...5)
g++ 7.3.0
sur Ubuntu 18.04.1 génère un avertissement qui indique le problème mentionné:Encore une fois , je dirai que cette réponse n'est qu'à AJOUTER aux autres réponses décrites ici (je pensais que ce point valait la peine d'être mentionné, mais je ne pouvais pas le décrire dans un commentaire).
la source