Je précise : les macros, c'est mal... surtout en C++. A mon avis, celle ci est particulièrement retors car elle cache un return et donc le flow réel du programme.
-- Richard
Bonjour à tous,
j'utilise DirectShow, et je me retrouve très souvent à employer ce genre de
syntaxe pour vérifier le bon déroulement du code:
hr = this->ConnectFilters(pGraph,pInfTee,pMux);
if (FAILED(hr))
{
ShowMessage("Impossible de connecter pInfTee à pMux");
return false;
}
FAILED étant une macro de DIrectShow permettant de vérifier que hr est
différent de S_OK, la valeur de retour indiquant que tout s'est bien passé.
Je voudrais créer une macro me permettant de réduire le code, quelque chose
du style:
TEST_FAILED(this->ConnectFilters(pGraph,pInfTee,pMux),"Impossible de
connecter pInfTee à pMux");
et qui ait le même comportement que le code ci-dessus...
Seulement je sais absolument pas utiliser les macros...
Je précise : les macros, c'est mal... surtout en C++. A mon avis, celle
ci est particulièrement retors car elle cache un return et donc le flow
réel du programme.
Je précise : les macros, c'est mal... surtout en C++. A mon avis, celle ci est particulièrement retors car elle cache un return et donc le flow réel du programme.
-- Richard
Loïc Joly
Michaël Delva wrote:
Bonjour à tous,
j'utilise DirectShow, et je me retrouve très souvent à employer ce genre de syntaxe pour vérifier le bon déroulement du code:
hr = this->ConnectFilters(pGraph,pInfTee,pMux); if (FAILED(hr)) { ShowMessage("Impossible de connecter pInfTee à pMux"); return false; }
FAILED étant une macro de DIrectShow permettant de vérifier que hr est différent de S_OK, la valeur de retour indiquant que tout s'est bien passé.
Je voudrais créer une macro me permettant de réduire le code, quelque chose du style:
TEST_FAILED(this->ConnectFilters(pGraph,pInfTee,pMux),"Impossible de connecter pInfTee à pMux");
Pourquoi une macro ? Voici une fonction qui fait une chose assez semblable :
...mais j'ai bien dit "au pire". L'idée des exceptions, c'est d'éviter de se coltiner des tests de valeurs de retour à tout bout de champ -- on teste l'erreur (i.e. try...catch...) au moment où on sait la traiter.
...mais j'ai bien dit "au pire". L'idée des exceptions, c'est d'éviter
de se coltiner des tests de valeurs de retour à tout bout de champ --
on teste l'erreur (i.e. try...catch...) au moment où on sait la
traiter.
...mais j'ai bien dit "au pire". L'idée des exceptions, c'est d'éviter de se coltiner des tests de valeurs de retour à tout bout de champ -- on teste l'erreur (i.e. try...catch...) au moment où on sait la traiter.
...mais j'ai bien dit "au pire". L'idée des exceptions, c'est d'éviter de se coltiner des tests de valeurs de retour à tout bout de champ -- on teste l'erreur (i.e. try...catch...) au moment où on sait la traiter.
Ok, parce que moi j'ai des fonctions qui ressemblent à ça:
...mais j'ai bien dit "au pire". L'idée des exceptions, c'est d'éviter
de se coltiner des tests de valeurs de retour à tout bout de champ --
on teste l'erreur (i.e. try...catch...) au moment où on sait la
traiter.
Ok, parce que moi j'ai des fonctions qui ressemblent à ça:
...mais j'ai bien dit "au pire". L'idée des exceptions, c'est d'éviter de se coltiner des tests de valeurs de retour à tout bout de champ -- on teste l'erreur (i.e. try...catch...) au moment où on sait la traiter.
Ok, parce que moi j'ai des fonctions qui ressemblent à ça:
Et sachant que mon main() est enchassé dans un bloc comme celui-ci (par défaut avec BCB6, mais je crois que c'est très recommandé de procéder de la sorte):
Et dernières questions: * lancer une exception comme ce que vous me conseillez permet-il de sortir de la fonction sans encombres? (tous mes pointeurs sont encapsulés par ATL, donc je pense ne pas avoir de soucis avec ça) * Dans le constructeur de certaines classes je pourrai donc être amené à lancer une exception... Avant d'aller lire le chapitre qui y est consacré dans le livre de Stroustrup demain, comment ça se passe dans ce cas?
Merci d'avance
Et sachant que mon main() est enchassé dans un bloc comme celui-ci (par
défaut avec BCB6, mais je crois que c'est très recommandé de procéder de la
sorte):
Et dernières questions:
* lancer une exception comme ce que vous me conseillez permet-il de sortir
de la fonction sans encombres? (tous mes pointeurs sont encapsulés par ATL,
donc je pense ne pas avoir de soucis avec ça)
* Dans le constructeur de certaines classes je pourrai donc être amené à
lancer une exception... Avant d'aller lire le chapitre qui y est consacré
dans le livre de Stroustrup demain, comment ça se passe dans ce cas?
Et sachant que mon main() est enchassé dans un bloc comme celui-ci (par défaut avec BCB6, mais je crois que c'est très recommandé de procéder de la sorte):
Et dernières questions: * lancer une exception comme ce que vous me conseillez permet-il de sortir de la fonction sans encombres? (tous mes pointeurs sont encapsulés par ATL, donc je pense ne pas avoir de soucis avec ça) * Dans le constructeur de certaines classes je pourrai donc être amené à lancer une exception... Avant d'aller lire le chapitre qui y est consacré dans le livre de Stroustrup demain, comment ça se passe dans ce cas?
Merci d'avance
Fabien LE LEZ
On 08 Sep 2004 00:03:40 GMT, "Michaël Delva" :
Comme ça dès qu'il y a une erreur je sors de la fonction... Ce qui visiblement est un manière de faire à éviter...
Avec les exceptions aussi, on sort de la fonction. Mais utiliser des valeurs de retour à tire-l'arigot est sans conteste une manière très lourde de s'en sortir.
Je te propose un exemple pour illustrer l'utilisation des exceptions et des hiérarchies d'exceptions. Note que le style du reste du programme (notamment la gestion de fichiers à la C) laisse à désirer, mais c'est juste pour l'exemple.
Supposons que tu veuilles utiliser les fonctions de gestion de fichiers de l'API Windows pour ouvrir un fichier, y lire deux nombres, et y écrire la somme de ces deux nombres, quand l'utilisateur clique sur un bouton.
class ExceptionGeneraleFichier: public std::exception { public: ExceptionGeneraleFichier (std::string const& nom_fonction) { std::string message_erreur= FormatMessage (GetLastError()); /* L'appel de ces deux fonctions de l'API Windows est plus compliqué, mais tu vois le principe... */ message= "La fonction " + nom_fonction + " a renvoyé l'erreur " + message_erreur + "."; }
void g (...) { ...= OuvrirFichier (...); int n1= LireNombre (...); int n2= LireNombre (...); EnregistreNombre (..., n1 + n2); FermerFichier (...); }
void f (...) { try { g (...); } catch (ExceptionManqueDePlace const&) { SupprimerFichiersTemporaires(); /* Si on manque de place sur disque dur, on supprime des fichiers inutiles... */ g(); /* ... puis on tente à nouveau */ } }
On 08 Sep 2004 00:03:40 GMT, "Michaël Delva"
<michael_delva@i_cant_remember.com>:
Comme ça dès qu'il y a une erreur je sors de la fonction...
Ce qui visiblement est un manière de faire à éviter...
Avec les exceptions aussi, on sort de la fonction. Mais utiliser des
valeurs de retour à tire-l'arigot est sans conteste une manière très
lourde de s'en sortir.
Je te propose un exemple pour illustrer l'utilisation des exceptions
et des hiérarchies d'exceptions. Note que le style du reste du
programme (notamment la gestion de fichiers à la C) laisse à désirer,
mais c'est juste pour l'exemple.
Supposons que tu veuilles utiliser les fonctions de gestion de
fichiers de l'API Windows pour ouvrir un fichier, y lire deux nombres,
et y écrire la somme de ces deux nombres, quand l'utilisateur clique
sur un bouton.
class ExceptionGeneraleFichier: public std::exception
{
public:
ExceptionGeneraleFichier (std::string const& nom_fonction)
{
std::string message_erreur= FormatMessage (GetLastError()); /*
L'appel de ces deux fonctions de l'API Windows est plus compliqué,
mais tu vois le principe... */
message= "La fonction " + nom_fonction
+ " a renvoyé l'erreur " + message_erreur + ".";
}
void g (...)
{
...= OuvrirFichier (...);
int n1= LireNombre (...);
int n2= LireNombre (...);
EnregistreNombre (..., n1 + n2);
FermerFichier (...);
}
void f (...)
{
try
{
g (...);
}
catch (ExceptionManqueDePlace const&)
{
SupprimerFichiersTemporaires(); /* Si on manque de place sur
disque dur, on supprime des fichiers inutiles... */
g(); /* ... puis on tente à nouveau */
}
}
Comme ça dès qu'il y a une erreur je sors de la fonction... Ce qui visiblement est un manière de faire à éviter...
Avec les exceptions aussi, on sort de la fonction. Mais utiliser des valeurs de retour à tire-l'arigot est sans conteste une manière très lourde de s'en sortir.
Je te propose un exemple pour illustrer l'utilisation des exceptions et des hiérarchies d'exceptions. Note que le style du reste du programme (notamment la gestion de fichiers à la C) laisse à désirer, mais c'est juste pour l'exemple.
Supposons que tu veuilles utiliser les fonctions de gestion de fichiers de l'API Windows pour ouvrir un fichier, y lire deux nombres, et y écrire la somme de ces deux nombres, quand l'utilisateur clique sur un bouton.
class ExceptionGeneraleFichier: public std::exception { public: ExceptionGeneraleFichier (std::string const& nom_fonction) { std::string message_erreur= FormatMessage (GetLastError()); /* L'appel de ces deux fonctions de l'API Windows est plus compliqué, mais tu vois le principe... */ message= "La fonction " + nom_fonction + " a renvoyé l'erreur " + message_erreur + "."; }
void g (...) { ...= OuvrirFichier (...); int n1= LireNombre (...); int n2= LireNombre (...); EnregistreNombre (..., n1 + n2); FermerFichier (...); }
void f (...) { try { g (...); } catch (ExceptionManqueDePlace const&) { SupprimerFichiersTemporaires(); /* Si on manque de place sur disque dur, on supprime des fichiers inutiles... */ g(); /* ... puis on tente à nouveau */ } }
* Dans le constructeur de certaines classes je pourrai donc être amené à lancer une exception... Avant d'aller lire le chapitre qui y est consacré dans le livre de Stroustrup demain, comment ça se passe dans ce cas?
L'objet n'est pas construit. Ce qui ne pose pas de problème, puisqu'en sortant du bloc "try", l'objet aurait été détruit de toutes façons.
Dans la ligne [1], m est forcément construit, car si Machin::Machin() a lancé une exception, on n'atteint jamais cette ligne.
-- ;-)
On 08 Sep 2004 00:15:56 GMT, "Michaël Delva"
<michael_delva@i_cant_remember.com>:
* Dans le constructeur de certaines classes je pourrai donc être amené à
lancer une exception... Avant d'aller lire le chapitre qui y est consacré
dans le livre de Stroustrup demain, comment ça se passe dans ce cas?
L'objet n'est pas construit. Ce qui ne pose pas de problème, puisqu'en
sortant du bloc "try", l'objet aurait été détruit de toutes façons.
* Dans le constructeur de certaines classes je pourrai donc être amené à lancer une exception... Avant d'aller lire le chapitre qui y est consacré dans le livre de Stroustrup demain, comment ça se passe dans ce cas?
L'objet n'est pas construit. Ce qui ne pose pas de problème, puisqu'en sortant du bloc "try", l'objet aurait été détruit de toutes façons.
Ainsi, si au cours de g() une exception non liée aux fichiers (du style, manque de mémoire), on considère ça comme une erreur fatale et le programme se quitte après avoir affiché le message sur cerr.
-- ;-)
On 08 Sep 2004 00:15:56 GMT, "Michaël Delva"
<michael_delva@i_cant_remember.com>:
Ou bien cela suffit-il
??
Fais gaffe, ta touche "?" se coince.
void toto()
{
Create_Graph();
}
Si les exceptions lancées sont des erreurs fatales, qui nécessitent
l'arrêt du programme, OK. Sinon, ça ne va pas.
Je me permets de modifier un peu mon programme précédent :
Ainsi, si au cours de g() une exception non liée aux fichiers (du
style, manque de mémoire), on considère ça comme une erreur fatale et
le programme se quitte après avoir affiché le message sur cerr.
Ainsi, si au cours de g() une exception non liée aux fichiers (du style, manque de mémoire), on considère ça comme une erreur fatale et le programme se quitte après avoir affiché le message sur cerr.
-- ;-)
Jonathan Mcdougall
Bonjour à tous,
j'utilise DirectShow, et je me retrouve très souvent à employer ce genre de
syntaxe pour vérifier le bon déroulement du code:
hr = this->ConnectFilters(pGraph,pInfTee,pMux);
Tu es au courant que this-> est redondant dans la plupart des cas?
if (FAILED(hr)) { ShowMessage("Impossible de connecter pInfTee à pMux"); return false; }
FAILED étant une macro de DIrectShow permettant de vérifier que hr est différent de S_OK, la valeur de retour indiquant que tout s'est bien passé.
Je voudrais créer une macro me permettant de réduire le code, quelque chose
du style:
Mauvaise idée, les macros sont à éviter en C++.
TEST_FAILED(this->ConnectFilters(pGraph,pInfTee,pMux),"Impossible de connecter pInfTee à pMux");
et qui ait le même comportement que le code ci-dessus...
Seulement je sais absolument pas utiliser les macros...
Concernant la macro, tu as déjà eu des réponses.
Une âme charitable pourrait-elle m'aider?
Une simple fonction serait plus adaptée à ton problème :
void f() { try { check(mafonction(), "probleme avec mafonction()"); check(mafonction2(), "probleme avec mafonction2()"); check(mafonction3(), "probleme avec mafonction3()"); } catch(MonException &) { // oups, clean up et sortie } }
Plusieurs designs sont possible, entre autre que check() mette le message dans l'exception et le catch() pourrait être chargé de l'afficher. Tout ceci dépend de ta situation et de tes connaissances.
Jonathan Mcdougall Montréal, Québec
Bonjour à tous,
j'utilise DirectShow, et je me retrouve très souvent à employer ce genre
de
syntaxe pour vérifier le bon déroulement du code:
hr = this->ConnectFilters(pGraph,pInfTee,pMux);
Tu es au courant que this-> est redondant dans la plupart des cas?
if (FAILED(hr))
{
ShowMessage("Impossible de connecter pInfTee à pMux");
return false;
}
FAILED étant une macro de DIrectShow permettant de vérifier que hr est
différent de S_OK, la valeur de retour indiquant que tout s'est bien
passé.
Je voudrais créer une macro me permettant de réduire le code, quelque
chose
du style:
Mauvaise idée, les macros sont à éviter en C++.
TEST_FAILED(this->ConnectFilters(pGraph,pInfTee,pMux),"Impossible de
connecter pInfTee à pMux");
et qui ait le même comportement que le code ci-dessus...
Seulement je sais absolument pas utiliser les macros...
Concernant la macro, tu as déjà eu des réponses.
Une âme charitable pourrait-elle m'aider?
Une simple fonction serait plus adaptée à ton problème :
void f()
{
try
{
check(mafonction(), "probleme avec mafonction()");
check(mafonction2(), "probleme avec mafonction2()");
check(mafonction3(), "probleme avec mafonction3()");
}
catch(MonException &)
{
// oups, clean up et sortie
}
}
Plusieurs designs sont possible, entre autre que check() mette le message
dans l'exception et le catch() pourrait être chargé de l'afficher. Tout
ceci dépend de ta situation et de tes connaissances.
void f() { try { check(mafonction(), "probleme avec mafonction()"); check(mafonction2(), "probleme avec mafonction2()"); check(mafonction3(), "probleme avec mafonction3()"); } catch(MonException &) { // oups, clean up et sortie } }
Plusieurs designs sont possible, entre autre que check() mette le message dans l'exception et le catch() pourrait être chargé de l'afficher. Tout ceci dépend de ta situation et de tes connaissances.