OVH Cloud OVH Cloud

gestion des exceptions

7 réponses
Avatar
Michael Moreno
Bonjour,

Il y a-t-il en C++ un "try... finally".

Apparemment non. Ou plutôt pas dans la norme.

Dans ce cas, pour respecter la norme, comment faîtes-vous pour éviter
une duplication du code ?

Ex :

m_IsRunning = true;
try
{
...
m_IsRunning = false;
}
catch(...)
{
m_IsRunning = false;
throw;
}

Il faut que je duplique le code au moins deux fois.

Merci pour votre aide.

--
Drakkhen

http://michael.moreno.free.fr/

7 réponses

Avatar
Fabien LE LEZ
On Sat, 26 Jun 2004 18:06:24 +0100, Michael Moreno
:

Dans ce cas, pour respecter la norme, comment faîtes-vous pour éviter
une duplication du code ?


Un peu de POO.

class GestionIsRunning
{
public:
GestionIsRunning (bool& indicateur_) : indicateur (indicateur_)
{ indicateur= true; }
~GestionIsRunning() { indicateur= false; }
private:
bool indicateur;
};


On peut ainsi remplacer :

static bool is_running;

void f()
{
m_IsRunning = true;
try
{
g();
m_IsRunning = false;
}
catch(...)
{
m_IsRunning = false;
throw;
}
}

par :

static bool is_running;

void f()
{
GestionIsRunning gestionnaire (is_running);
g();
}

Que l'appel à g() génère une exception ou non, "is_running" passe à
"true" dans la première ligne de f(), et repasse à "false" quand on
sort de f(), que ce soit par une sortie normale ou par une exception.



--
schtroumpf schtroumpf

Avatar
Fabien LE LEZ
On Sat, 26 Jun 2004 18:06:24 +0100, Michael Moreno
:

Dans ce cas, pour respecter la norme, comment faîtes-vous pour éviter
une duplication du code ?


Un peu de POO.

class GestionIsRunning
{
public:
GestionIsRunning (bool& indicateur_) : indicateur (indicateur_)
{ indicateur= true; }
~GestionIsRunning() { indicateur= false; }
private:
bool& indicateur;
};


On peut ainsi remplacer :

static bool is_running;

void f()
{
m_IsRunning = true;
try
{
g();
m_IsRunning = false;
}
catch(...)
{
m_IsRunning = false;
throw;
}
}

par :

static bool is_running;

void f()
{
GestionIsRunning gestionnaire (is_running);
g();
}

Que l'appel à g() génère une exception ou non, "is_running" passe à
"true" dans la première ligne de f(), et repasse à "false" quand on
sort de f(), que ce soit par une sortie normale ou par une exception.



--
schtroumpf schtroumpf

Avatar
Michael Moreno
Merci bien je n'aurai jamais pensé à cette solution !

--
Drakkhen

http://michael.moreno.free.fr/
Avatar
Franck Branjonneau
Michael Moreno écrivait:

Bonjour,

Il y a-t-il en C++ un "try... finally".


Non.

Dans ce cas, pour respecter la norme, comment faîtes-vous pour éviter
une duplication du code ?


struct EviterUneDuplication {

bool & isRunning_;


EviterUneDuplication(
bool & isRunning):
isRunning_(isRunning) {

isRunning= true;
}

~EviterUneDuplication() {

isRunning= false;
}
};

EviterUneDuplication const dummy(m_IsRunning);
try {

// ...

} catch(...) {

throw;
}
--
Franck Branjonneau

Avatar
Luc Hermitte
Bonsoir,

Michael Moreno wrote in
news::
Il y a-t-il en C++ un "try... finally".



Pour compléter les autres réponses, cet article d'Andrei Alexandrescu est
des plus intéressants.
http://www.cuj.com/documents/s€00/cujcexp1812alexandr/alexandr.htm

--
Luc Hermitte <hermitte at free.fr>
FAQ de <news:fr.comp.lang.c++> :
<http://www.cmla.ens-cachan.fr/Utilisateurs/dosreis/C++/FAQ/>
Dejanews : <http://groups.google.com/advanced_group_search>

Avatar
Arnaud Debaene
Michael Moreno wrote:
Merci bien je n'aurai jamais pensé à cette solution !


Et pou une solution générique pour ce genre de choses, voire ScopeGuard par
exemple
(http://www.cuj.com/documents/s€00/cujcexp1812alexandr/alexandr.htm)

Arnaud

Avatar
James Kanze
Michael Moreno writes:

|> Il y a-t-il en C++ un "try... finally".

Non.

|> Apparemment non. Ou plutôt pas dans la norme.

Il n'y en a pas. Il n'y en a pas comme extension dans les compilateurs
que je connais non plus.

En général, je crois qu'on n'en ressent pas le besoin.

|> Dans ce cas, pour respecter la norme, comment faîtes-vous pour
|> éviter une duplication du code ?

|> Ex :

|> m_IsRunning = true;
|> try
|> {
|> ...
|> m_IsRunning = false;
|> }
|> catch(...)
|> {
|> m_IsRunning = false;
|> throw;
|> }

class BoolResetter
{
public:
BoolResetter( bool& var ) : myVar( var ) { myVar = true ; }
~BoolResetter() { myVar = false }
private:
bool& myVar ;
} ;

{
BoolResetter isRunning( m_IsRunning ) ;
// ...
}

À une certaine époque, j'avais pensé à l'idée de faire une classe
implicite (__local_context ?) avec la contexte du bloc, et avec,
potentiellement, des mots clés supplémentaires pour l'utiliser. Parmi
d'autre, un « cleanup », qui aurait permit d'écrire :

{
m_IsRunning = true ;
cleanup { m_IsRunning = false } ;
// ...
}

Ça aurait généré une classe implicite avec accès à la contexte locale,
et avec le code en {...} comme destructeur.

Il n'y avait pas beaucoup d'intérêt, alors je l'ai laissé tomber.

--
James Kanze
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France +33 (0)1 30 23 00 34