En concevant ma première bibliothèque C ++ «sérieuse», je me pose la question:
Est-ce un bon style de dériver ses exceptions std::exception
et ses descendants?!
Même après avoir lu
- Conception de classes d'exception
- Qu'est-ce qu'un «bon nombre» d'exceptions à implémenter pour ma bibliothèque?
Je ne suis toujours pas sûr. Parce que, en plus des pratiques courantes (mais peut-être pas bonnes), je suppose, en tant qu'utilisateur de bibliothèque, qu'une fonction de bibliothèque ne lancerait std::exception
s que lorsque les fonctions de bibliothèque standard échouent dans l'implémentation de la bibliothèque, et elle ne peut rien y faire. Mais quand même, lors de l'écriture du code d'application, pour moi, c'est très pratique, et aussi à mon humble avis, il suffit de jeter un std::runtime_error
. Mes utilisateurs peuvent également compter sur l'interface minimale définie, comme what()
ou sur des codes.
Et par exemple, mon utilisateur fournit des arguments défectueux, quoi de plus pratique que de lancer un std::invalid_argument
, n'est-ce pas? Donc, combiné avec l'utilisation encore courante de std :: exception, je vois dans le code d'autres: Pourquoi ne pas aller plus loin et dériver de votre classe d'exception personnalisée (par exemple lib_foo_exception) et aussi de std::exception
.
Pensées?
lib_foo_exception
classe dérive std::exception
, l'utilisateur de la bibliothèque attraperait lib_foo_exception
simplement en attrapant std::exception
, en plus de ne capturer que la bibliothèque. Je pourrais donc aussi demander à ma classe racine d'exception de bibliothèque d'hériter de std :: exception .
lib_foo_exception
?" Avec l'héritage de std::exception
vous pouvez le faire par catch(std::exception)
OU par catch(lib_foo_exception)
. Sans dériver de std::exception
, vous l'attraperiez si et seulement si , par catch(lib_foo_exception)
.
catch(...)
. C'est là parce que le langage permet le cas que vous envisagez (et pour les bibliothèques "mal se comporter"), mais ce n'est pas la meilleure pratique moderne.
catch
sites plus grossiers et plus généraux , ainsi que les transactions plus grossières qui modélisent une opération utilisateur. Si vous le comparez à des langages qui ne promeuvent pas l'idée d'une capture généralisée std::exception&
, par exemple, ils ont souvent beaucoup plus de code avec des try/catch
blocs intermédiaires concernés par des erreurs très spécifiques, ce qui diminue quelque peu la généralité du traitement des exceptions car il commence à se placer un accent beaucoup plus marqué sur la gestion manuelle des erreurs, ainsi que sur toutes les erreurs disparates qui pourraient éventuellement se produire.
std::exception
n'est pas parce que vous héritez de que vous lancez unstd::exception
. En outre,std::runtime_error
héritestd::exception
en premier lieu, et lawhat()
méthode vientstd::exception
, nonstd::runtime_error
. Et vous devez absolument créer vos propres classes d'exceptions au lieu de lancer des exceptions génériques telles questd::runtime_error
.