OVH Cloud OVH Cloud

est-ce une bonne astuce?

36 réponses
Avatar
dark poulpo
alors voila:

imaginons ce cas


void func()
{

ouvre(a);
ouvre(b);

test();
if (error()) { ferme(a); ferme(b); return; } // je le met sur un ligne pour
visualiser les 2 cas plus simplement

testa();
if (error()) { ferme(a); ferme(b); return; }

testb();
if (error()) { ferme(a); ferme(b); return; }

testc();
if (error()) { ferme(a); ferme(b); return; }

....
....

ferme(a);
ferme(b);
return;
}
//////////////////////////////
par
/////////////////////////////

void func()
{

ouvre(a);
ouvre(b);

while(1)
{
test();
if (error()) break;

testa();
if (error()) break;

testb();
if (error()) break;

testc();
if (error()) break;

....
....
break;
}
ferme(a);
ferme(b);
return;
}

qu'en pensez-vous?

10 réponses

1 2 3 4
Avatar
Patrick Mézard
dark poulpo wrote:
alors voila:

imaginons ce cas


void func()
{

ouvre(a);
ouvre(b);

test();
if (error()) { ferme(a); ferme(b); return; } // je le met sur un ligne pour
visualiser les 2 cas plus simplement

testa();
if (error()) { ferme(a); ferme(b); return; }

testb();
if (error()) { ferme(a); ferme(b); return; }

testc();
if (error()) { ferme(a); ferme(b); return; }

....
....

ferme(a);
ferme(b);
return;
}
//////////////////////////////
par
/////////////////////////////

void func()
{

ouvre(a);
ouvre(b);

while(1)
{
test();
if (error()) break;

testa();
if (error()) break;

testb();
if (error()) break;

testc();
if (error()) break;

....
....
break;
}
ferme(a);
ferme(b);
return;
}

qu'en pensez-vous?


Tu peux chercher RAII (Resource Aquisition Is Initialization) dans les
archives du groupe ou sur n'importe quel autre newsgroup/forum dédié au
C++. C'est l'idiome courant en pour réaliser ça.

En supposant que a et b soient d'un même type Truc :


void func()
{

struct TrucGuard
{
TrucGuard(Truc& t) : t_(t) {}
~TrucGuard() {ferme(t_);}
Truc& t_;
};

ouvre(a);
TrucGuard t_a(a);
ouvre(b);
TrucGuard t_b(b);

while(1)
{
test();
if (error()) return;

testa();
if (error()) return;

testb();
if (error()) return;

testc();
if (error()) return;
}


La solution ci-dessus à l'avantage de ne pas toucher au code de Truc.
Ceci dit, il me semble encore plus probable que tu puisses faire de Truc
un véritable objet, avec "ouvre" et "ferme" comme méthode. et lui faire
appeler éventuellement "ferme" dans son destructeur (et pourquoi pas
"ouvre" dans son constructeur), et réaliser directement la fonction de
TrucGuard.

Patrick Mézard

Avatar
dark poulpo
oué je saisis ton exemple, en sortant de la procedure les destructeurs sont
appelés, c pas con.


--
*************************
le bureau 3D pour windows
http://www.syndesk3d.fr.st
*************************
"Patrick Mézard" a écrit dans le message news:
ceh0gh$i11$
dark poulpo wrote:
alors voila:

imaginons ce cas


void func()
{

ouvre(a);
ouvre(b);

test();
if (error()) { ferme(a); ferme(b); return; } // je le met sur un ligne
pour


visualiser les 2 cas plus simplement

testa();
if (error()) { ferme(a); ferme(b); return; }

testb();
if (error()) { ferme(a); ferme(b); return; }

testc();
if (error()) { ferme(a); ferme(b); return; }

....
....

ferme(a);
ferme(b);
return;
}
//////////////////////////////
par
/////////////////////////////

void func()
{

ouvre(a);
ouvre(b);

while(1)
{
test();
if (error()) break;

testa();
if (error()) break;

testb();
if (error()) break;

testc();
if (error()) break;

....
....
break;
}
ferme(a);
ferme(b);
return;
}

qu'en pensez-vous?


Tu peux chercher RAII (Resource Aquisition Is Initialization) dans les
archives du groupe ou sur n'importe quel autre newsgroup/forum dédié au
C++. C'est l'idiome courant en pour réaliser ça.

En supposant que a et b soient d'un même type Truc :


void func()
{

struct TrucGuard
{
TrucGuard(Truc& t) : t_(t) {}
~TrucGuard() {ferme(t_);}
Truc& t_;
};

ouvre(a);
TrucGuard t_a(a);
ouvre(b);
TrucGuard t_b(b);

while(1)
{
test();
if (error()) return;

testa();
if (error()) return;

testb();
if (error()) return;

testc();
if (error()) return;
}


La solution ci-dessus à l'avantage de ne pas toucher au code de Truc.
Ceci dit, il me semble encore plus probable que tu puisses faire de Truc
un véritable objet, avec "ouvre" et "ferme" comme méthode. et lui faire
appeler éventuellement "ferme" dans son destructeur (et pourquoi pas
"ouvre" dans son constructeur), et réaliser directement la fonction de
TrucGuard.

Patrick Mézard



Avatar
Matthieu Moy
"dark poulpo" writes:

while(1)
{
....
....
break;
}


Pour moi, si il y a "while(1)", c'est qu'il y a une boucle, donc, je
trouve qu'utiliser une boucle while pour ton astuce nuit plutôt à la
lisibilité.

--
Matthieu

Avatar
Alexandre Bacquart
dark poulpo wrote:

alors voila:

imaginons ce cas

[...]


'vais me faire taper sur les doigts, mais vu que personne va oser le
proposer... soyons fou : l'infâme goto peut être utile dans ce cas (les
doigts, pas la tête merci). Mais ça manque de classe, si j'ose dire :)

--
Tek

Avatar
Fabien LE LEZ
On Sat, 31 Jul 2004 22:37:09 +0200, "dark poulpo"
:

qu'en pensez-vous?


Je m'étonne que personne n'ait encore parlé d'exceptions dans le
présent thread...


--
;-)

Avatar
Fabien LE LEZ
On Sat, 31 Jul 2004 22:37:09 +0200, "dark poulpo"
:

qu'en pensez-vous?


L'email de Patrick donne bien entendu les solutions canoniques.

Toutefois, pour ce cas précis, on peut commencer par améliorer un peu
le code :

bool test_ok()
{
test();
return error();
}
bool testa_ok()
{
testa();
return error();
}
bool testb_ok()
{
testa();
return error();
}

void func()
{
ouvre(a);
ouvre(b);

if (test_ok() && testa_ok() && testb_ok())
{
....
....
}

ferme(a);
ferme(b);
return;
}

Avoir plusieurs "return;" dans une fonction (ou des "break;") n'est
pas toujours une mauvaise chose, mais ça peut être un symptôme
d'erreur de design.

Note que le code ci-dessus est vraisemblablement incorrect : si une
fonction 'testx_ok', ou un "....", lance une exception, "ferme()"
n'est jamais appelé.


--
;-)

Avatar
Richard Delorme
dark poulpo wrote:
alors voila:

imaginons ce cas


void func()
{

ouvre(a);
ouvre(b);

test();
if (error()) { ferme(a); ferme(b); return; } // je le met sur un ligne pour
visualiser les 2 cas plus simplement

testa();
if (error()) { ferme(a); ferme(b); return; }

testb();
if (error()) { ferme(a); ferme(b); return; }

testc();
if (error()) { ferme(a); ferme(b); return; }

....
....

ferme(a);
ferme(b);
return;
}


Pour éviter les return multiples ou des goto, il suffit d'avoir des if
imbriqués :

ouvre(a);
ouvre(b);

test();
if (!error()) {
testa() {
if (!error()) {
testb() {
if (!error()) {
testc()
if (!error()) {
.....
.....
}
}
}
}

ferme(a);
ferme(b);
return

Cela dit, je ne suis pas sûr que l'on gagne en lisibilité.
La meilleure solution est sans doute de faire du C++ orienté objet, avec
ouvre et ferme respectivement dans le constructeur et le destructeur et
des try/catch pour gérer les erreurs, comme déjà indiqués par d'autres
contibuteurs.

while(1)
{
test();
if (error()) break;

testa();
if (error()) break;

testb();
if (error()) break;

testc();
if (error()) break;

....
....
break;
}
ferme(a);
ferme(b);
return;
}

qu'en pensez-vous?


A mon avis c'est du code spaghetti avec des goto déguisés en break.

--
Richard

Avatar
Florent 'flure' C.
Le Sat, 31 Jul 2004 22:37:09 +0200, dark poulpo a écrit :

qu'en pensez-vous?


Pourquoi pas plutôt ceci :

void func()
{
try {
ouvre(a);
ouvre(b);
test();
} finally {
ferme(a);
ferme(b);
}
}

--
Florent "flure" C.
Décrypter l'@ pour répondre
Coders don't die, they just JMP without RET !

Avatar
Jean-Marc Bourguet
"Florent 'flure' C." writes:

Le Sat, 31 Jul 2004 22:37:09 +0200, dark poulpo a écrit :

qu'en pensez-vous?


Pourquoi pas plutôt ceci :


C'est peut-être du Java, certainement pas du C++.

} finally {


A+

--
Jean-Marc
FAQ de fclc++: http://www.cmla.ens-cachan.fr/~dosreis/C++/FAQ
C++ FAQ Lite en VF: http://www.ifrance.com/jlecomte/c++/c++-faq-lite/index. html
Site de usenet-fr: http://www.usenet-fr.news.eu.org


Avatar
dark poulpo
--
*************************
le bureau 3D pour windows
http://www.syndesk3d.fr.st
*************************
"dark poulpo" a écrit dans le message news:
ceguu9$5io$
alors voila:

imaginons ce cas

qu'en pensez-vous?





merci pour vos reponses,
il se trouve que les testes error() sont des fonctions a moi qui
verifientleta dune variable, doisje faire une declanchement d'exception dans
ce cas la?
pour moi, les exceptions sont la pour eviter certain plantage/des erreurs
syteme, dans mon ca ca n'est pas pour eviter un plantage. donc est-ce
vraiment utile?

1 2 3 4