try - catch en C++ - C++ - Programmation
Marsh Posté le 08-05-2005 à 10:59:54
déjà, ta classe d'exception, tu là fais hérité de quelque chose dans <stdexcep>
ensuite, tu attrapes l'exception par &
et ne déclare pas le type d'exception lancé
pour finir : n'inclue pas de code, contente toi de définir différentes classes d'exception
Marsh Posté le 08-05-2005 à 11:52:29
Code :
|
pour bien faire
Marsh Posté le 08-05-2005 à 22:06:04
Citation : catch(Xixor::ErreurCompression& ex) |
pas de const ?
Marsh Posté le 08-05-2005 à 22:17:08
si tu en veux ...
mais pour rendre ça drôle, je devrais jeter des exceptions à base de pointeurs
Marsh Posté le 08-05-2005 à 22:23:18
en fait, note que comme l'objet de l'exception est en ta possession, tu peux t'en servir comme tu veux. Par exemple, faire
ex.message = "Meilleur message de diagnostique";
throw;
ce que tu t'interdis avec le const.
Marsh Posté le 08-05-2005 à 22:31:19
mais je te sens joueur ce soir : comment ferais-tu pour centraliser la gestion des exceptions, pour ne pas à avoir à taper plusieurs fois toutes la même série de bloc catch ?
Marsh Posté le 09-05-2005 à 00:18:13
A la demande express de mon grand ami push qui me rapelle fort justement et avec le tact qui lui est coutumier que j'ai posté ici
Taz a écrit : mais je te sens joueur ce soir |
ah mais pas du tout, il ne fallait pas prendre ma question comme etant un défi mais plutot comme l'expression de ma surprise, etant donné que je t'ai souvent vu brandir bien haut l'etendart du "const machin &" dans la gestion d'exception
Citation : comment ferais-tu pour centraliser la gestion des exceptions, pour ne pas à avoir à taper plusieurs fois toutes la même série de bloc catch ? |
votre question ne m'est pas tres claire mon cher et depuis 6 mois que je fais du C de bagnard, les exceptions, hein, je vais finir par meme pu trop de quoi il en retourne
Marsh Posté le 09-05-2005 à 00:41:27
comment tu ferais pour factoriser le traitement d'erreur ? dans l'exemple, j'ai deux try, et à chaque fois, plusieurs catch. Et ça fait plein de code en double pour traiter l'exception.
Marsh Posté le 09-05-2005 à 01:09:12
bah jbricolerais un truc a base de fonctions, vu que la seule chose qui change c'est le block try. M'enfin ne me fait pas trop passer pour un con trop longtemps et donne nous ta fine reponse
Marsh Posté le 09-05-2005 à 01:12:37
Code :
|
Code :
|
et hop, un répartisseur d'exception, sans dynamic_cast
Marsh Posté le 09-05-2005 à 01:18:35
moué
Marsh Posté le 09-05-2005 à 11:01:13
C'est quoi ce complot hérétique nocturne contre la religion C++ ?
C'etait pour montrer à chrisbk qu'il existe aussi du C++ de bagnard ?
Marsh Posté le 09-05-2005 à 11:11:47
chui clairement pas fan de cette bidouille et la macro n'est pas la pour arranger les choses
fab >> du C++ de bagnard je connais, j'en ai meme fait a mes debuts (du beau C with classes )
Marsh Posté le 09-05-2005 à 11:14:04
spa une bidouille. Et la macro, elle set à pas grand chose.
Le dernier conseil du jour : ne jamais relancé une exception avec un 'throw e;'. Toujours utilisé 'throw;'. Sinon tu fous en l'air le polymorphisme.
Marsh Posté le 09-05-2005 à 11:22:42
Et à quoi te sert le polymorphisme dans ta bidouille ? Et à quoi ça te sert de faire hériter tes classes d'exceptions de std::exception (ou une de ces filles) ?
Sans compter que la moindre modification dans le bloc try ou dans le nom des classes d'exceptions t'oblige à tout recoder ...
Marsh Posté le 09-05-2005 à 11:26:26
...
réfléchi d'abord à mon message précédent. En quoi
Code :
|
est un bug alors que
Code :
|
est correcte ?
Marsh Posté le 09-05-2005 à 11:33:53
++fab a écrit : Et à quoi te sert le polymorphisme dans ta |
cet argument m'a l'air quand meme sacrement foireux
Marsh Posté le 09-05-2005 à 11:34:48
ma remarque à 11h22 n'etait pas du tout destiné à ton dernier conseil du jour, mais à ta bidouille.
Qu'est ce que ça apporte par rapport à ce que tu avais écrit plus haut ? (en bien)
# try
# {
# Xixor::compresse("foo" );
# Xixor::decompresse("" );
# }
# catch(const std::exception& ex)
# {
# std::cerr << "Une erreur s'est produite : "
# << ex.what() << '\n';
# }
Marsh Posté le 09-05-2005 à 11:42:06
chrisbk a écrit : cet argument m'a l'air quand meme sacrement foireux |
Le nom des classes d'exceptions, c'est qqchose que je change environ 3 ou 4 fois, mais c'est une lacune personnelle. J'ai toujours tendance à sous-estimer l'importance d'une conception tot dans le projet de la hiérarchie des classes d'exception. Malgré les conseils du BS
Marsh Posté le 09-05-2005 à 11:51:46
ben tu peux centraliser ton code de gestion d'erreur. Notemment si tu dois prendre des décisions (genre ouvrir un message d'erreur). Je te dis pas qu'il faut utiliser que ça, je te dis qu'il y a de la place pour les deux.
Marsh Posté le 09-05-2005 à 15:02:25
alors vous abandonnez ?
Code :
|
sans compiler, vous pensez que ça donne quoi ça ?
Marsh Posté le 09-05-2005 à 15:54:57
parce que l'exception jetee est une My::Exception par lien polymorphique mais lorsque on fait trow e; on perd l'informartion sur le caractere dynamique du type de l'exception (pas sur , et pas sur que ca ve dire qulequechose) qui devien My::Exception
Marsh Posté le 09-05-2005 à 15:55:29
Taz a écrit : et pourquoi ? |
throw; ça propage l'exception.
throw e; ça déclenche une exception du type statique de e. e construit par [edit]COPY[\edit] constructor.
Marsh Posté le 09-05-2005 à 16:05:40
plus précisément, lors d'un throw My::badException(), une copie temporaire est faite, et elle perdure tant qu'il y a un gestionnaire capable de traiter l'exception. Si l'affaire se termine par autre chose que throw; la copie temporaire est détruite et désallouée !
Marsh Posté le 09-05-2005 à 23:13:12
J'ai fini par réaliser l'objectif de ton trick. Vu qu'il était enrober de glaise, je l'ai pris tel quel et j'ai cru que tu rennonçais au polymorphisme ... d'ou ma surprise.
Ton trick sert donc à réaliser une centralisation décentrée (dans le corps d'une fonction) de la gestion des exceptions. C'est un poil obfuscant à mon gout, mais ça sépare encore plus le code d'erreur du reste.
On pourrait peut etre s'en servir dans un cas, sans obfuscations aucune :
Supposons que l'on ai 2 hiérarchies de classes d'exceptions (distinctes).
On récupère habituellement les exceptions dans le plus pur style "les enfants d'abord" (pour éviter le dynamic_cast<> ). Sauf que lorsque l'on a deux hiérarchies distinctes, c'est pas évident de rendre la gestion très lisible.
A ce moment la, Taz exception's trick :
Code :
|
Marsh Posté le 09-05-2005 à 23:14:55
ben à chaque fois tu écris autant de catch ...
# catch(const std::exception& e)
# { GESTION_ERREUR1("toto" ) }
# catch(const nonstd::exception& e)
# { GESTION_ERREUR2("toto" ) }
tu duplique à chaque fois. le but c'est foutre ça dans une fonction
Marsh Posté le 09-05-2005 à 23:15:01
Et encore, c'est criticable puisqu'il faut faire 2 fonctions, qu'on va quand meme essayer de mettre dans le meme namespace.
Marsh Posté le 09-05-2005 à 23:16:14
ReplyMarsh Posté le 09-05-2005 à 23:17:05
bah la tu perds des informations de types, et tu dois dynamic_cast'er pour en savoir plus dans tes trucs de gestions d'erreurs.
Marsh Posté le 09-05-2005 à 23:19:40
Regarde bien, y a 2 macros ... qui appelle chacune une fonction différente, mais ça n'apparait pas OK.
Marsh Posté le 09-05-2005 à 23:21:27
ben alors de quoi tu parles ? c'est exactement la même chose. Je t'ai jamais dit que tu devais ne faire qu'une seule et unique fonction.
Marsh Posté le 08-05-2005 à 10:51:27
Bonjour,
je débute un peu avec le C++ et je me demandais si il était possible de faire de la gestion d'erreur en try-catch qui reprenne l'éxecution du code après le throw, et pas après le bloc catch.
Exemple :
Le but serait ici que le bloc catch n'affiche qu'un message d'avertissement si erreur.code est 0 et que l'exécution continue normalement, et qu'il quitte le programme si erreur.code vaut 1.
Code :
....
struct Erreur
{
string message;
int code;
};
....
string compresse(const string& data, char flag) throw (Erreur)
{
......
if (data2[i]=='a')
{
Erreur er1;
er1.message ="avertissement";
er1.code =0;
throw er1;
}
.....
return data2;
}
string decompresse(const string& rledata, char flag) throw (Erreur)
{
....
if (rledata2[i+1]==flag)
{
Erreur er2;
er2.message="erreur : flag apres flag";
er2.code=1;
throw er2;
}
.....
return rledata2;
}
int main()
{
....
try
{
string str2(compresse(str1,'#'));
// le programme doit s'exécuter jusqu'ici, même si compresse lève une exception
....
string str3(decompresse(str2,'#'));
// mais plus là (si decompresse lève une exception)
}
catch (Erreur erreur)
{
if (erreur.code==0)
{
cout <<erreur.message<<endl;
// LA JUSTE UN AVERTISSEMENT
}
else
{
cout <<erreur.message<<endl;
return 0; // pour quitter le programme
}
}
}
Voilà merci d'avance pour vos réponses et bon dimanche!
A+