openclassroom - Exception standard ou personnalisée en C++?



c++ using exceptions (3)

Généralement, vous devez lancer des instances de classes dans l'en-tête ou les sous-classes de stdexcept . Quelle classe a du sens dépend du problème spécifique. Je pense que lancer des instances de "classes de catégories" std::logic_error et std::runtime_error est rarement utile car elles n'ont aucune signification inhérente; ils sont utilisés pour distinguer les deux situations principales où des exceptions peuvent se produire:

  • Les sous-classes de std::logic_error devraient être lancées par une fonction si elle est appelée, mais toutes les conditions préalables ne sont pas remplies. L'exception est la faute de l'appelant car elle n'a pas fourni les conditions préalables nécessaires. Pour cette catégorie, vous devez généralement choisir entre lancer et comportement indéfini; c'est un compromis entre robustesse et efficacité (par exemple std::vector::at() vs std::vector::operator[] . Ces exceptions ne peuvent souvent pas être gérées, elles sont le résultat de bogues dans le programme.

  • Les sous-classes de std::runtime_error doivent être lancées par une fonction si toutes les conditions préalables sont remplies mais que la fonction ne peut pas répondre aux postconditions ou aux invariants pour des raisons indépendantes de la volonté du programme (par exemple, un fichier n'existe pas, la connexion réseau est perdue , ou pas assez de mémoire est disponible). Ces exceptions devraient généralement être traitées.

Je pense que les classes d'erreurs logiques disponibles (par exemple invalid_argument ) sont souvent assez bonnes, car si elles sont levées, le code doit généralement être corrigé, et il n'y a aucune raison pour des routines de manipulation élaborées. D'autre part, les classes d'erreurs d' exécution dans la bibliothèque standard sont par nature beaucoup moins flexibles et couvrent principalement les zones où la bibliothèque standard elle-même doit lever des exceptions. Pour votre application, vous devriez presque toujours hériter de ces classes d'erreurs d'exécution. Par exemple, une classe gérant la ressource X du système d'exploitation doit lancer X_creation_error qui hérite de std::runtime_error si le constructeur ne parvient pas à allouer la ressource.

L'héritage virtuel multiple est souvent utile avec les classes d'exception. Vous pouvez hériter de std::runtime_error ou d'autres classes stdexcept , de certaines "classes de marqueurs" spécifiques à votre bibliothèque, et de boost::exception pour obtenir les avantages supplémentaires de la bibliothèque Boost.Exception . Le tutoriel Boost.Exception est fortement recommandé, en particulier les types Exception en tant que balises sémantiques simples et Utilisation de l'héritage virtuel dans les types d'exception .

Pour un code de bibliothèque, est-il préférable de créer et de lancer une classe d'exception personnalisée (library :: Exception), ou simplement de lancer des exceptions standard (runtime_error, invalid_argument, etc.)?


Answer #1

IMHO exception personnalisée. Les clients de votre bibliothèque apprécieront cela. Il saura exactement ce qui soulève l'exception.


Answer #2

Il est généralement préférable de spécialiser (hériter) une exception standard et de la lancer.

De cette façon, il sera possible de l'attraper en tant qu'exception générique juste en attrapant une std::exception , mais vous pourriez aussi attraper spécifiquement votre type d'exception personnalisé si vous avez besoin d'un code plus spécialisé.

Voir aussi ce Faq C ++ sur ce qu'il faut jeter.





standards