exception c ++: lancer std :: ssortingng

Je voudrais lancer une exception lorsque mes méthodes C ++ rencontrent quelque chose de bizarre et ne peuvent pas récupérer. Est-il correct de lancer un pointeur std::ssortingng ?

Voici ce que j’avais hâte de faire:

 void Foo::Bar() { if(!QueryPerformanceTimer(&m_baz)) { throw new std::ssortingng("it's the end of the world!"); } } void Foo::Caller() { try { this->Bar(); // should throw } catch(std::ssortingng *caught) { // not quite sure the syntax is OK here... std::cout << "Got " << caught << std::endl; } } 

Oui. std::exception est la classe d’exception de base dans la bibliothèque standard C ++. Vous souhaiterez peut-être éviter d’utiliser des chaînes en tant que classes d’exception car elles peuvent elles-mêmes lancer une exception lors de l’utilisation. Si cela se produit, alors où seras-tu?

boost a un excellent document sur le bon style pour les exceptions et la gestion des erreurs. Ça vaut le coup de lire.

Quelques principes:

  1. vous avez une classe de base std :: exception, vos exceptions devraient en dériver. De cette façon, le gestionnaire d’exceptions générales a encore des informations.

  2. Ne lancez pas de pointeurs mais objectez, de cette façon la mémoire est gérée pour vous.

Exemple:

 struct MyException : public std::exception { std::ssortingng s; MyException(std::ssortingng ss) : s(ss) {} ~MyException() throw () {} // Updated const char* what() const throw() { return s.c_str(); } }; 

Et puis utilisez-le dans votre code:

 void Foo::Bar(){ if(!QueryPerformanceTimer(&m_baz)){ throw MyException("it's the end of the world!"); } } void Foo::Caller(){ try{ this->Bar();// should throw }catch(MyException& caught){ std::cout<<"Got "< 

Tous ces travaux:

 #include  using namespace std; //Good, because manual memory management isn't needed and this uses //less heap memory (or no heap memory) so this is safer if //used in a low memory situation void f() { throw ssortingng("foo"); } //Valid, but avoid manual memory management if there's no reason to use it void g() { throw new ssortingng("foo"); } //Best. Just a pointer to a ssortingng literal, so no allocation is needed, //saving on cleanup, and removing a chance for an allocation to fail. void h() { throw "foo"; } int main() { try { f(); } catch (ssortingng s) { cout << s << endl; } try { g(); } catch (string* s) { cout << *s << endl; delete s; } try { h(); } catch (const char* s) { cout << s << endl; } return 0; } 

Vous devriez préférer h à f à g. Notez que dans l'option la moins préférable, vous devez libérer la mémoire explicitement.

Ça marche, mais je ne le ferais pas si j’étais toi. Vous ne semblez pas supprimer ces données de tas lorsque vous avez terminé, ce qui signifie que vous avez créé une fuite de mémoire. Le compilateur C ++ prend soin de s’assurer que les données d’exception sont maintenues en vie même si la stack est supprimée, alors ne vous sentez pas obligé d’utiliser le tas.

Incidemment, lancer une std::ssortingng n’est pas la meilleure approche pour commencer. Vous aurez beaucoup plus de flexibilité si vous utilisez un object wrapper simple. Il peut simplement encapsuler une ssortingng pour le moment, mais peut-être qu’à l’avenir, vous voudrez inclure d’autres informations, comme certaines données qui ont provoqué l’exception ou peut-être un numéro de ligne (très commun, cela). Vous ne voulez pas changer toutes vos manipulations d’exception à chaque endroit de votre base de code, alors prenez la grande route maintenant et ne jetez pas d’objects bruts.

En plus de probablement lancer quelque chose dérivé de std :: exception, vous devriez jeter des provisoires anonymes et attraper par référence:

 void Foo::Bar(){ if(!QueryPerformanceTimer(&m_baz)){ throw std::ssortingng("it's the end of the world!"); } } void Foo:Caller(){ try{ this->Bar();// should throw }catch(std::ssortingng& caught){ // not quite sure the syntax is ok here... std::cout<<"Got "< 
  • Vous devriez lancer des provisoires anonymes pour que le compilateur traite la durée de vie de l'object de ce que vous lancez - si vous lancez quelque chose de nouveau depuis le tas, quelqu'un d'autre doit le libérer.
  • Vous devez attraper des références pour empêcher les objects de trancher

.

Voir Meyer's "Effective C ++ - 3rd edition" pour plus de détails ou visitez le site https://www.securecoding.cert.org/.../ERR02-A.+Throw+anonymous+temporaries+and+catch+by+reference

Le moyen le plus simple de lancer une exception en C ++:

 #include  using namespace std; void purturb(){ throw "Cannot purturb at this time."; } int main() { try{ purturb(); } catch(const char* msg){ cout << "We caught a message: " << msg << endl; } cout << "done"; return 0; } 

Cela imprime:

 We caught a message: Cannot purturb at this time. done 

Si vous attrapez l'exception levée, l'exception est contenue et le programme continuera. Si vous n'attrapez pas l'exception, le programme existe et imprime:

This application has requested the Runtime to terminate it in an unusual way. Please contact the application's support team for more information.

Bien que cette question soit assez ancienne et a déjà reçu une réponse, je veux juste append une note sur la manière de gérer correctement les exceptions en C ++ 11 :

Utilisez std::nested_exception et std::throw_with_nested

À mon avis, leur utilisation conduit à une conception d’exception plus propre et rend inutile la création d’une hiérarchie de classes d’exceptions.

Notez que cela vous permet d’ obtenir une trace sur vos exceptions dans votre code sans avoir besoin d’un débogueur ou d’une journalisation fastidieuse. Il est décrit ici et ici sur StackOverflow, comment écrire un gestionnaire d’exceptions correct qui va renvoyer les exceptions nestedes.

Comme vous pouvez le faire avec n’importe quelle classe dérivée, vous pouvez append beaucoup d’informations à un tel backtrace! Vous pouvez également jeter un coup d’œil à mon fichier MWE sur GitHub , où un backtrace ressemblerait à ceci:

 Library API: Exception caught in function 'api_function' Backtrace: ~/Git/mwe-cpp-exception/src/detail/Library.cpp:17 : library_function failed ~/Git/mwe-cpp-exception/src/detail/Library.cpp:13 : could not open file "nonexistent.txt"