Y a vraiment pas une autre solution ? Cette solution est basee sur le "Out Of Scope" et dans certains cas je trouve que c'est limitant.
Au contraire, c'est l'une des approches les plus puissantes que l'on ait pour la gestion des ressources (au sens large, pas seulement la mémoire), et c'est la solution "standard" en C++ . Qu'est ce qui te semble limitant là dedans au juste? Donnes-nous un exemple où ce mécanisme ne serait pas satisfaisant.
Y a vraiment pas une autre solution ?
Cette solution est basee sur le "Out Of Scope" et dans certains cas je
trouve que c'est limitant.
Au contraire, c'est l'une des approches les plus puissantes que l'on ait
pour la gestion des ressources (au sens large, pas seulement la mémoire), et
c'est la solution "standard" en C++ . Qu'est ce qui te semble limitant là
dedans au juste? Donnes-nous un exemple où ce mécanisme ne serait pas
satisfaisant.
Y a vraiment pas une autre solution ? Cette solution est basee sur le "Out Of Scope" et dans certains cas je trouve que c'est limitant.
Au contraire, c'est l'une des approches les plus puissantes que l'on ait pour la gestion des ressources (au sens large, pas seulement la mémoire), et c'est la solution "standard" en C++ . Qu'est ce qui te semble limitant là dedans au juste? Donnes-nous un exemple où ce mécanisme ne serait pas satisfaisant.
Arnaud
Matthieu Moy
"Arnaud Debaene" writes:
Donnes-nous un exemple où ce mécanisme ne serait pas satisfaisant.
Il me semble qu'en C++, le try-finally n'existe pas.
Je me demande par consequent quelle est la facon pour eviter la repetition de code du genre
EnterCriticalSection(...);
{ Lock l();
Je ne suis pas sûr que la déclaration d'une fonction "l" ne prenant pas de paramètre et retournant un object Lock soit d'un grand secours ;-) Plutôt : Lock l;
Tout à fait.
Marc Boyer -- Je ne respecte plus le code de la route à vélo depuis une double fracture due au fait que j'étais le seul à le respecter.
Bertrand Motuelle wrote:
Marc Boyer wrote:
In article <mn.72ac7d4c21f8a6b0.21643@free.fr>, Michael Moreno wrote:
Bonjour,
Il me semble qu'en C++, le try-finally n'existe pas.
Je me demande par consequent quelle est la facon pour eviter la
repetition de code du genre
EnterCriticalSection(...);
{
Lock l();
Je ne suis pas sûr que la déclaration d'une fonction "l" ne prenant
pas de paramètre et retournant un object Lock soit d'un grand secours
;-)
Plutôt :
Lock l;
Tout à fait.
Marc Boyer
--
Je ne respecte plus le code de la route à vélo depuis une double fracture
due au fait que j'étais le seul à le respecter.
Il me semble qu'en C++, le try-finally n'existe pas.
Je me demande par consequent quelle est la facon pour eviter la repetition de code du genre
EnterCriticalSection(...);
{ Lock l();
Je ne suis pas sûr que la déclaration d'une fonction "l" ne prenant pas de paramètre et retournant un object Lock soit d'un grand secours ;-) Plutôt : Lock l;
Tout à fait.
Marc Boyer -- Je ne respecte plus le code de la route à vélo depuis une double fracture due au fait que j'étais le seul à le respecter.
Marc Boyer
Matthieu Moy wrote:
"Arnaud Debaene" writes:
Donnes-nous un exemple où ce mécanisme ne serait pas satisfaisant.
Ca devient un peu plus complexe, mais c'est normal puisqu'un principe de RAII est de libérer les ressources en ordre inverse de leur aquisition, et que tu veux faire là le contraire.
Sans trop chercher, je ferais un truc du genre:
Lock *A= new Lock(); ... Lock *B= new Lock(); ... delete A; ... delete B;
Bon, après, l'échec possible de new introduit un peut de travail en plus. Peut-être qu'avec des aspects du langage que je maîtrise mal (placement new ou factory), on pourrait éviter ce travers. Faudrait je pense alors lancer une autre discussion avec un titre qui ammène les gens plus experts que moi à se pencher sur ton problème.
Marc Boyer -- Je ne respecte plus le code de la route à vélo depuis une double fracture due au fait que j'étais le seul à le respecter.
Ca devient un peu plus complexe, mais c'est normal puisqu'un
principe de RAII est de libérer les ressources en ordre inverse
de leur aquisition, et que tu veux faire là le contraire.
Sans trop chercher, je ferais un truc du genre:
Lock *A= new Lock();
...
Lock *B= new Lock();
...
delete A;
...
delete B;
Bon, après, l'échec possible de new introduit un peut de travail
en plus. Peut-être qu'avec des aspects du langage que je maîtrise mal
(placement new ou factory), on pourrait éviter ce travers.
Faudrait je pense alors lancer une autre discussion avec un titre
qui ammène les gens plus experts que moi à se pencher sur ton problème.
Marc Boyer
--
Je ne respecte plus le code de la route à vélo depuis une double fracture
due au fait que j'étais le seul à le respecter.
Ca devient un peu plus complexe, mais c'est normal puisqu'un principe de RAII est de libérer les ressources en ordre inverse de leur aquisition, et que tu veux faire là le contraire.
Sans trop chercher, je ferais un truc du genre:
Lock *A= new Lock(); ... Lock *B= new Lock(); ... delete A; ... delete B;
Bon, après, l'échec possible de new introduit un peut de travail en plus. Peut-être qu'avec des aspects du langage que je maîtrise mal (placement new ou factory), on pourrait éviter ce travers. Faudrait je pense alors lancer une autre discussion avec un titre qui ammène les gens plus experts que moi à se pencher sur ton problème.
Marc Boyer -- Je ne respecte plus le code de la route à vélo depuis une double fracture due au fait que j'étais le seul à le respecter.
Cette solution est basee sur le "Out Of Scope" et dans certains cas je
trouve que c'est limitant.
Quand l'idiome ne convient pas, il ne convient pas. C'est sûr. La question initiale était par rapport à try/finally, ce qui introduite une portée aussi. Dans les deux cas, si la durée de vie déterminée par la portée d'une variable automatique ne te convient pas, il faut utiliser d'autre chose. (Note bien que quelqu'un a cité boost::shared_ptr. Or, un boost::shared_ptr ne suit pas la portée d'une variable automatique.)
C'est un peu l'avantage d'un moyen extra linguistique pour gerer les resssources. Comment, par exemple, faire en Java qu'une synchronisation ne suis pas la durée de vie d'un bloc ? La contrapartie, évidemment, c'est qu'il faut que tu fasses quelque chose -- try/finally, ou un destructeur -- quand tu veux une durée de vie d'un bloc.
-- James Kanze GABI Software http://www.gabi-soft.fr 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
Cette solution est basee sur le "Out Of Scope" et dans certains cas
je
trouve que c'est limitant.
Quand l'idiome ne convient pas, il ne convient pas. C'est sûr. La
question initiale était par rapport à try/finally, ce qui introduite
une
portée aussi. Dans les deux cas, si la durée de vie déterminée par
la
portée d'une variable automatique ne te convient pas, il faut utiliser
d'autre chose. (Note bien que quelqu'un a cité boost::shared_ptr. Or,
un
boost::shared_ptr ne suit pas la portée d'une variable automatique.)
C'est un peu l'avantage d'un moyen extra linguistique pour gerer les
resssources. Comment, par exemple, faire en Java qu'une synchronisation
ne suis pas la durée de vie d'un bloc ? La contrapartie, évidemment,
c'est qu'il faut que tu fasses quelque chose -- try/finally, ou un
destructeur -- quand tu veux une durée de vie d'un bloc.
--
James Kanze GABI Software http://www.gabi-soft.fr
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
Cette solution est basee sur le "Out Of Scope" et dans certains cas je
trouve que c'est limitant.
Quand l'idiome ne convient pas, il ne convient pas. C'est sûr. La question initiale était par rapport à try/finally, ce qui introduite une portée aussi. Dans les deux cas, si la durée de vie déterminée par la portée d'une variable automatique ne te convient pas, il faut utiliser d'autre chose. (Note bien que quelqu'un a cité boost::shared_ptr. Or, un boost::shared_ptr ne suit pas la portée d'une variable automatique.)
C'est un peu l'avantage d'un moyen extra linguistique pour gerer les resssources. Comment, par exemple, faire en Java qu'une synchronisation ne suis pas la durée de vie d'un bloc ? La contrapartie, évidemment, c'est qu'il faut que tu fasses quelque chose -- try/finally, ou un destructeur -- quand tu veux une durée de vie d'un bloc.
-- James Kanze GABI Software http://www.gabi-soft.fr 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
kanze
Matthieu Moy wrote:
"Arnaud Debaene" writes:
Donnes-nous un exemple où ce mécanisme ne serait pas satisfaisant.
Pas plus qu'avec try/finally. Ou plutôt avec les mêmes moyens. Dans ce cas-là, la RAII sert surtout de sauvegarde ; il assure que la ressource soit libérée, même en cas d'exception, mais la libération en cas normal est manuelle.
Sinon, il y a toujours quelque chose du genre :
std::deque< boost::shared_ptr > locks ; locks.push_front( new Lock( A ) ) ; locks.push_front( new Lock( B ) ) ;
(Sauf que je ne crois pas que l'ordre des destructeurs n'est garantie dans les collections standard. Mais ce ne serait pas difficile d'écrire un wrapper qui le fait.)
-- James Kanze GABI Software http://www.gabi-soft.fr 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
Pas plus qu'avec try/finally. Ou plutôt avec les mêmes moyens. Dans
ce
cas-là, la RAII sert surtout de sauvegarde ; il assure que la
ressource
soit libérée, même en cas d'exception, mais la libération en cas
normal
est manuelle.
Sinon, il y a toujours quelque chose du genre :
std::deque< boost::shared_ptr >
locks ;
locks.push_front( new Lock( A ) ) ;
locks.push_front( new Lock( B ) ) ;
(Sauf que je ne crois pas que l'ordre des destructeurs n'est garantie
dans les collections standard. Mais ce ne serait pas difficile
d'écrire
un wrapper qui le fait.)
--
James Kanze GABI Software http://www.gabi-soft.fr
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
Pas plus qu'avec try/finally. Ou plutôt avec les mêmes moyens. Dans ce cas-là, la RAII sert surtout de sauvegarde ; il assure que la ressource soit libérée, même en cas d'exception, mais la libération en cas normal est manuelle.
Sinon, il y a toujours quelque chose du genre :
std::deque< boost::shared_ptr > locks ; locks.push_front( new Lock( A ) ) ; locks.push_front( new Lock( B ) ) ;
(Sauf que je ne crois pas que l'ordre des destructeurs n'est garantie dans les collections standard. Mais ce ne serait pas difficile d'écrire un wrapper qui le fait.)
-- James Kanze GABI Software http://www.gabi-soft.fr 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
Alexis Nikichine
Matthieu Moy wrote:
"Arnaud Debaene" writes:
Donnes-nous un exemple où ce mécanisme ne serait pas satisfaisant.
Je m'étais fait une classe "Lock" de ce goût là, qui possédait une méthode "earlyUnlock", pour unlocker mon mutex avant que le destructeur ne le fasse lui-même.
Cela dit, je me permet d'attirer l'attention sur les ScopeGuard de Alexandrescu, qui me paraissent bien résoudre ce problème, et permettent aussi d'éviter d'écrire trop de petites classes ad-hoc:
Je m'étais fait une classe "Lock" de ce goût là, qui possédait une
méthode "earlyUnlock", pour unlocker mon mutex avant que le destructeur
ne le fasse lui-même.
Cela dit, je me permet d'attirer l'attention sur les ScopeGuard de
Alexandrescu, qui me paraissent bien résoudre ce problème, et permettent
aussi d'éviter d'écrire trop de petites classes ad-hoc:
Je m'étais fait une classe "Lock" de ce goût là, qui possédait une méthode "earlyUnlock", pour unlocker mon mutex avant que le destructeur ne le fasse lui-même.
Cela dit, je me permet d'attirer l'attention sur les ScopeGuard de Alexandrescu, qui me paraissent bien résoudre ce problème, et permettent aussi d'éviter d'écrire trop de petites classes ad-hoc:
Ca devient un peu plus complexe, mais c'est normal puisqu'un principe de RAII est de libérer les ressources en ordre inverse de leur aquisition, et que tu veux faire là le contraire.
Sans trop chercher, je ferais un truc du genre:
Lock *A= new Lock(); ... Lock *B= new Lock(); ... delete A; ... delete B;
Mais c'est bien sur non exception-safe, et c'est une solution comme celle présentée par James qu'il faut prendre (ou revenir au try/catch).
Marc Boyer -- Je ne respecte plus le code de la route à vélo depuis une double fracture due au fait que j'étais le seul à le respecter.
In article <cporjn$4ng$2@news.cict.fr>, Marc Boyer wrote:
Ca devient un peu plus complexe, mais c'est normal puisqu'un
principe de RAII est de libérer les ressources en ordre inverse
de leur aquisition, et que tu veux faire là le contraire.
Sans trop chercher, je ferais un truc du genre:
Lock *A= new Lock();
...
Lock *B= new Lock();
...
delete A;
...
delete B;
Mais c'est bien sur non exception-safe, et c'est une solution comme
celle présentée par James qu'il faut prendre (ou revenir au try/catch).
Marc Boyer
--
Je ne respecte plus le code de la route à vélo depuis une double fracture
due au fait que j'étais le seul à le respecter.
Ca devient un peu plus complexe, mais c'est normal puisqu'un principe de RAII est de libérer les ressources en ordre inverse de leur aquisition, et que tu veux faire là le contraire.
Sans trop chercher, je ferais un truc du genre:
Lock *A= new Lock(); ... Lock *B= new Lock(); ... delete A; ... delete B;
Mais c'est bien sur non exception-safe, et c'est une solution comme celle présentée par James qu'il faut prendre (ou revenir au try/catch).
Marc Boyer -- Je ne respecte plus le code de la route à vélo depuis une double fracture due au fait que j'étais le seul à le respecter.
Olivier Huet
Bonjour,
Sans trop chercher, je ferais un truc du genre:
Lock *A= new Lock(); ... Lock *B= new Lock(); ... delete A; ... delete B;
J'ai déjà (peut-être à tort) écrit du code ressemblant à ça, avec des variables automatiques - genre (pour reprendre une classe proche) :
{ Lock l(A); Lock l(B); ... }
en comptant sur le fait que les destructeur * seraient * bien appelées en ordre inverse des constructeurs, et j'ai vérifié avec le compilateur que j'utilisait dans ce cas (VC++ 6).
En fait, ça me semblait logique que cela fonctionne comme ça, mais finalement, était-ce standard : a-t-on ce genre de garantie ???
Olivier Huet
Bonjour,
Sans trop chercher, je ferais un truc du genre:
Lock *A= new Lock();
...
Lock *B= new Lock();
...
delete A;
...
delete B;
J'ai déjà (peut-être à tort) écrit du code ressemblant à ça, avec des
variables automatiques - genre (pour reprendre une classe proche) :
{
Lock l(A);
Lock l(B);
...
}
en comptant sur le fait que les destructeur * seraient * bien appelées
en ordre inverse des constructeurs, et j'ai vérifié avec le compilateur
que j'utilisait dans ce cas (VC++ 6).
En fait, ça me semblait logique que cela fonctionne comme ça, mais
finalement, était-ce standard : a-t-on ce genre de garantie ???
Lock *A= new Lock(); ... Lock *B= new Lock(); ... delete A; ... delete B;
J'ai déjà (peut-être à tort) écrit du code ressemblant à ça, avec des variables automatiques - genre (pour reprendre une classe proche) :
{ Lock l(A); Lock l(B); ... }
en comptant sur le fait que les destructeur * seraient * bien appelées en ordre inverse des constructeurs, et j'ai vérifié avec le compilateur que j'utilisait dans ce cas (VC++ 6).
En fait, ça me semblait logique que cela fonctionne comme ça, mais finalement, était-ce standard : a-t-on ce genre de garantie ???
Olivier Huet
Gabriel Dos Reis
Olivier Huet writes:
| en comptant sur le fait que les destructeur * seraient * bien appelées | en ordre inverse des constructeurs, et j'ai vérifié avec le | compilateur que j'utilisait dans ce cas (VC++ 6). | | En fait, ça me semblait logique que cela fonctionne comme ça, mais | finalement, était-ce standard : a-t-on ce genre de garantie ???
Oui.
-- Gaby
Olivier Huet <huet-pasdespamsvp-.o@caramail.com> writes:
| en comptant sur le fait que les destructeur * seraient * bien appelées
| en ordre inverse des constructeurs, et j'ai vérifié avec le
| compilateur que j'utilisait dans ce cas (VC++ 6).
|
| En fait, ça me semblait logique que cela fonctionne comme ça, mais
| finalement, était-ce standard : a-t-on ce genre de garantie ???
| en comptant sur le fait que les destructeur * seraient * bien appelées | en ordre inverse des constructeurs, et j'ai vérifié avec le | compilateur que j'utilisait dans ce cas (VC++ 6). | | En fait, ça me semblait logique que cela fonctionne comme ça, mais | finalement, était-ce standard : a-t-on ce genre de garantie ???