Quelle est la différence entre std::runtime_error
et std::exception
? Quelle est l'utilisation appropriée de chacun? Pourquoi sont-ils différents en premier lieu?
la source
Quelle est la différence entre std::runtime_error
et std::exception
? Quelle est l'utilisation appropriée de chacun? Pourquoi sont-ils différents en premier lieu?
std::exception
est la classe dont le seul but est de servir de classe de base dans la hiérarchie des exceptions. Il n'a pas d'autres utilisations. En d'autres termes, conceptuellement, il s'agit d'une classe abstraite (même si elle n'est pas définie comme une classe abstraite au sens C ++ du terme).
std::runtime_error
est une classe plus spécialisée, descendant de std::exception
, destinée à être lancée en cas de diverses erreurs d' exécution . Il a un double objectif. Il peut être lancé par lui-même, ou il peut servir de classe de base à divers types encore plus spécialisés d'exceptions d'erreur d'exécution, tels que std::range_error
, std::overflow_error
etc. Vous pouvez définir vos propres classes d'exceptions descendant de std::runtime_error
, ainsi que vous pouvez définir votre propre exception classes descendant de std::exception
.
Tout comme std::runtime_error
, la bibliothèque standard contient std::logic_error
, également descendant de std::exception
.
L'intérêt d'avoir cette hiérarchie est de donner à l'utilisateur la possibilité d'utiliser toute la puissance du mécanisme de gestion des exceptions C ++. Puisque la clause 'catch' peut intercepter des exceptions polymorphes, l'utilisateur peut écrire des clauses 'catch' qui peuvent intercepter des types d'exceptions à partir d'un sous-arbre spécifique de la hiérarchie d'exceptions. Par exemple, catch (std::runtime_error& e)
capturera toutes les exceptions du std::runtime_error
sous-arbre, laissant toutes les autres passer (et remonter plus haut dans la pile d'appels).
PS La conception d'une hiérarchie de classes d'exceptions utile (qui vous permettrait de capturer uniquement les types d'exceptions qui vous intéressent à chaque point de votre code) est une tâche non triviale. Ce que vous voyez dans la bibliothèque C ++ standard est une approche possible, proposée par les auteurs du langage. Comme vous le voyez, ils ont décidé de diviser tous les types d'exceptions en «erreurs d'exécution» et «erreurs logiques» et vous ont laissé procéder à partir de là avec vos propres types d'exceptions. Il existe, bien sûr, d'autres moyens de structurer cette hiérarchie, qui pourraient être plus appropriés dans votre conception.
Mise à jour: portabilité Linux vs Windows
Comme Loki Astari et unixman83 l'ont noté dans leur réponse et leurs commentaires ci-dessous, le constructeur de la exception
classe ne prend aucun argument selon le standard C ++. Microsoft C ++ a un constructeur prenant des arguments dans la exception
classe, mais ce n'est pas standard. La runtime_error
classe a un constructeur prenant des arguments ( char*
) sur les deux plates-formes, Windows et Linux. Pour être portable, une meilleure utilisation runtime_error
.
(Et rappelez-vous, ce n'est pas parce qu'une spécification de votre projet indique que votre code ne doit pas s'exécuter sous Linux, cela ne signifie pas qu'il ne doit jamais s'exécuter sous Linux.)
std::exception
. Bien sûr, toutesstd
choses en jettent des classes dérivées, mais il n'y a absolument aucune raison de ne lancer que desstd::exception
objets dérivés.std::exception
devrait être considéré (notez le considéré) la base abstraite de la hiérarchie d'exceptions standard. En effet, il n'y a pas de mécanisme pour passer un message spécifique (pour ce faire, vous devez dériver et spécialiserwhat()
). Il n'y a rien qui vous empêche d'utiliser std :: exception et pour les applications simples, cela peut être tout ce dont vous avez besoin.std::runtime_error
d'autre part, a des constructeurs valides qui acceptent une chaîne comme message. Quandwhat()
est appelé, un pointeur de char const est retourné qui pointe sur une chaîne C qui a la même chaîne que celle qui a été passée au constructeur.la source
std::exception(std::string)
. Maintenant, je me rends compte que je dois lancerstd::runtime_error
si je veux que mon code fonctionne sous Linux (GCC).