puis-je obtenir la description d'une exception interceptée parC++ obtenir la description d'une exception pris des prises (...) bloquer
catch(...)
bloc? quelque chose comme .what() de std :: exception.
puis-je obtenir la description d'une exception interceptée parC++ obtenir la description d'une exception pris des prises (...) bloquer
catch(...)
bloc? quelque chose comme .what() de std :: exception.
Il y a un truc que vous pourriez être en mesure d'utiliser:
catch(...) {
handle_exception();
}
void handle_exception() {
try {
throw;
} catch (const std::exception &e) {
std::cout << e.what() << "\n";
} catch (const int i) {
std::cout << i << "\n";
} catch (const long l) {
std::cout << l << "\n";
} catch (const char *p) {
std::cout << p << "\n";
} catch (...) {
std::cout << "nope, sorry, I really have no clue what that is\n";
}
et ainsi de suite, pour autant de types différents que vous pensez peut-être jeté. Si vous ne savez vraiment rien sur ce qui pourrait être jeté, alors même l'avant-dernier est faux, car quelqu'un pourrait lancer un char*
qui ne pointe pas vers une chaîne terminée par nul.
Généralement, c'est une mauvaise idée de lancer tout ce qui n'est pas un std::exception
ou une classe dérivée. La raison std::exception
existe est de permettre à tout le monde de lancer et attraper des objets avec lesquels ils peuvent faire quelque chose d'utile. Dans un programme de jouet où vous voulez juste sortir de là et ne peut même pas être dérangé pour inclure un en-tête standard, OK, peut-être jeter un int
ou un littéral de chaîne. Je ne pense pas que je ferais cette partie d'une interface formelle. Toutes les exceptions que vous lancez font partie de votre interface formelle, même si vous avez oublié de les documenter.
Salut; C'est une excellente réponse. J'ai cherché pendant un certain temps à trouver des preuves dans les documents de normes que c'est un comportement standard, mais j'ai été incapable d'en trouver. Savez-vous avec certitude que c'est un comportement standard? (C'est-à-dire, entrer un nouveau bloc 'try' dans un' catch (...) {} 'et réenvoyer une exception afin de déterminer son type.) – NHDaly
Travailler depuis la mémoire: recherchez le texte sur la durée de vie du exception actuelle (jusqu'à ce que vous quittiez la clause catch), et l'effet d'un 'throw' sans opérande (relance l'exception actuelle). –
Ce bloc peut attraper un int, ou un const char *, ou quoi que ce soit. Comment le compilateur peut-il savoir comment décrire quelque chose alors qu'il n'en sait rien? Si vous souhaitez obtenir des informations sur une exception, vous devez connaître le type.
" Comment le compilateur peut-il savoir comment décrire quelque chose quand il le sait? rien à ce sujet? - +1, mais en réalité, le compilateur en sait un peu plus à ce sujet. Le mécanisme d'exception doit stocker * certaines informations de type, car il doit faire correspondre l'objet d'exception avec les clauses catch. Mais la norme ne définit pas cette information ou ne permet pas d'y accéder, c'est un détail d'implémentation caché. –
Cette information de type est loin d'être suffisante pour effectuer cette opération, et aucune implémentation ne pourrait changer cela. – Puppy
ressemble à un défi ;-) Une extension du compilateur '__what()' qui renvoie une chaîne contenant le nom typeinfo de l'exception actuelle (facile à implémenter) suivi de plusieurs caractères décrivant sa valeur (en pratique, vous pouvez facilement mais plutôt types intégrés, et la plupart de la bibliothèque standard, et peut-être avoir des implémentations de base pour les types définis par l'utilisateur). Bien sûr, cela signifierait que le compilateur émettait un code bloaty pour chaque type pour faire sa conversion de chaîne, mais ensuite pensez combien de 'operator <<' existe déjà. Le faire pour tout, bien sûr pas possible. –
Si vous savez que vous ne jetez std :: exception ou sous-classes, essayez
catch(std::exception& e) {...e.what()... }
Sinon, comme l'a écrit DeadMG, puisque vous pouvez jeter (presque) tout, vous ne pouvez pas prendre quoi que ce soit au sujet de ce que vous avez pris.
Normalement, catch (...) ne devrait être utilisé que comme dernier moyen de défense lors de l'utilisation de bibliothèques externes mal écrites ou documentées. Donc, vous devez utiliser une hiérarchie
catch(my::specialException& e) {
// I know what happened and can handle it
... handle special case
}
catch(my::otherSpecialException& e) {
// I know what happened and can handle it
... handle other special case
}
catch(std::exception& e) {
//I can at least do something with it
logger.out(e.what());
}
catch(...) {
// something happened that should not have
logger.out("oops");
}
Comment nous avons nos exceptions mises en œuvre est que, nous avons nos propres classes d'exception, qui sont tous dérivés de std::exception
..
Nos exceptions contiendront Message d'exception, fonction nom, nom de fichier et ligne où des exceptions sont générées. Ceux-ci sont tous utiles non seulement pour afficher les messages, mais peut également être utilisé pour la journalisation qui aide à diagnostiquer l'exception assez facilement. Ainsi, nous obtenons toute l'information sur les exceptions générées.
Rappelez-vous les exceptions sont us pour obtenir des informations sur ce qui s'est mal passé. Ainsi, chaque bit d'information aide à cet égard ..
Depuis C++ 11 vous pouvez capturer l'exception actuelle avec un pointeur:
std::exception_ptr p; // default initialization is to nullptr
try {
throw 7;
}
catch(...)
{
p = std::current_exception();
}
Ce se comporte comme un pointeur intelligent; tant qu'il y a au moins un pointeur pointant vers l'objet d'exception, il n'est pas détruit.
plus tard (peut-être même dans une autre fonction), vous pouvez prendre des mesures d'une manière similaire à la réponse actuelle haut:
try {
if (p)
std::rethrow_exception(p);
}
catch(int x)
{
}
catch(std::exception &y)
{
}
#include <iostream>
#include <exception>
#include <typeinfo>
#include <stdexcept>
int main()
{
try {
throw ...; // throw something
}
catch(...)
{
std::exception_ptr p = std::current_exception();
std::clog <<(p ? p.__cxa_exception_type()->name() : "null") << std::endl;
}
return 1;
}
Ce n'est pas standard ou portable. Il repose sur * des détails spécifiques à l'implémentation * qui diffèrent entre les compilateurs. 'std :: exception_ptr' est un pointeur partagé intelligent vers un type * unspecified *, donc il n'y a aucune garantie que' __cxa_exception_type() 'existe –
En C de 11 rethrowing de ' std :: current_exception' peut être utilisé pour obtenir le message d'exception 'what' dans le bloc catch-all: http://stackoverflow.com/a/37222762/5447906 –