OVH Cloud OVH Cloud

constructeur auto avortif. Ca existe?

9 réponses
Avatar
olivier fourcade
Bonjour a tous,

Mon titre n'etait probablement pas tres clair alors je vais expliquer ;-).

Je voudrait faire un objet dont la construction puisse être interomput. Ca
me donne quelque chose du genre :

T::T():
var1(0), var2(3)
{
...
if(test==ERROR)
{
...
delete this;
}
}

Mon probleme est que je ne vois pas comment faire en sorte que le
constructeur retourne un pointeur NULL, plutot qu'un pointeur sur lui même
alors qu'il va se détruire (impossible d'employer return NULL).

A chaque fois qu'il y a ERROR, il retourne un pointeur non NULL et mon
programme croit l'objet construit et le traite comme tel :-( !!!
J'ai bien essayé ca pour regler le probleme:

T* t=new T(&t); <- l'appel au constructeur dans le programme

T::T(T** t):
var1(0), var2(3)
{
...
if(test==ERROR)
{
...
*t=NULL;
delete this;
}
}

Mais cela ne fonctionne pas.

Quelqu'un a t'il une solution ou bien est ce conceptuellement impossible (il
semblerait, mais j'aimai bien l'idée :-o).

Merci d'avance.

Olivier

9 réponses

Avatar
Fabien LE LEZ
On Sat, 16 Aug 2003 01:57:55 +0200, "olivier fourcade"
wrote:

Quelqu'un a t'il une solution


Deux solutions :

1/ Lancer une exception
2/ Mettre une indicateur booleen "ok" à "false", et demander à
l'utilisateur de tester la validité de l'objet après construction.

--
Tout sur fr.* (FAQ, etc.) : http://www.usenet-fr.net/fur/
et http://www.aminautes.org/forums/serveurs/tablefr.html
Archives : http://groups.google.com/advanced_group_search
http://www.usenet-fr.net/fur/usenet/repondre-sur-usenet.html

Avatar
olivier fourcade
"Fabien LE LEZ" a écrit dans le message de news:

On Sat, 16 Aug 2003 01:57:55 +0200, "olivier fourcade"

Deux solutions :

1/ Lancer une exception
2/ Mettre une indicateur booleen "ok" à "false", et demander à
l'utilisateur de tester la validité de l'objet après construction.



La 2/ me semble la plus basique mais possède de tres bonne chance de
fonctionner, bien que cela rendra le tout moins jolie (et puis laisser
l'utilisateur tester la validité de l'objet ne me plait pas beaucoup même qi
le seule utilisateur sera surement moi ;-) )

Lancer une exception. Ca ma laire très sympatique, sauf que je ne sais
qu'intercepter une exception. Bon et bien il va faloir que je me documente
car mon livre de c++ ne parle absoluement pas de ca (mais de toute facon je
savais dejà qu'il etait limité comme bouquin).

Merci pour la réponse, je vais me pencher sur la 1/

Olivier

Avatar
Fabien LE LEZ
On Sat, 16 Aug 2003 02:15:10 +0200, "olivier fourcade"
wrote:

Bon et bien il va faloir que je me documente
car mon livre de c++ ne parle absoluement pas de ca


T'es sûr que c'est pas juste un livre de C, avec un petit malin qui a
griffonné "++" sur le titre ? C'est le cas d'une grande partie des
livres sensés parler de C++ :-(


--
Tout sur fr.* (FAQ, etc.) : http://www.usenet-fr.net/fur/
et http://www.aminautes.org/forums/serveurs/tablefr.html
Archives : http://groups.google.com/advanced_group_search
http://www.usenet-fr.net/fur/usenet/repondre-sur-usenet.html

Avatar
olivier fourcade
"Fabien LE LEZ" a écrit dans le message de news:



T'es sûr que c'est pas juste un livre de C, avec un petit malin qui a
griffonné "++" sur le titre ? C'est le cas d'une grande partie des
livres sensés parler de C++ :-(


Oui, je crois bien que c'est un truc du genre. En fait c'est du C enrobé de

C++ un peu vieillot apparemment. Pour l'instant je fais avec, en faisant des
mises à jour de temps en temps (En plus je sais que c'est mal, mais je suis
douer pour lélanger du C avec le C++ :-( ). Mais bon là il va vraiment
faloir que j'en change :-o.

Avatar
Patrick Mézard
Deux solutions :

1/ Lancer une exception
2/ Mettre une indicateur booleen "ok" à "false", et demander à
l'utilisateur de tester la validité de l'objet après construction.



La 2/ me semble la plus basique mais possède de tres bonne chance de
fonctionner, bien que cela rendra le tout moins jolie (et puis laisser
l'utilisateur tester la validité de l'objet ne me plait pas beaucoup même
qi

le seule utilisateur sera surement moi ;-) )

Lancer une exception. Ca ma laire très sympatique, sauf que je ne sais
qu'intercepter une exception. Bon et bien il va faloir que je me documente
car mon livre de c++ ne parle absoluement pas de ca (mais de toute facon
je

savais dejà qu'il etait limité comme bouquin).


http://www.gotw.ca/gotw/066.htm dont le titre est "Constructor Failures"
donne des explications assez intéressantes sur le sujet. Il y a en plus une
discussion assez sympathique sur pourquoi (1) devrait être utilisée au lieu
de (2).
Mais avoir un vrai bouquin sous la main ne fait pas de mal non plus.

Patrick Mézard


Avatar
drkm
"Patrick Mézard" writes:

http://www.gotw.ca/gotw/066.htm dont le titre est "Constructor
Failures" donne des explications assez intéressantes sur le
sujet. Il y a en plus une discussion assez sympathique sur pourquoi
(1) devrait être utilisée au lieu de (2).

Mais avoir un vrai bouquin sous la main ne fait pas de mal non plus.


Tu veux parler de « Exceptional C++ » ?-)

--drkm

Avatar
Fabien SK
On Sat, 16 Aug 2003 02:04:30 +0200, Fabien LE LEZ wrote:

On Sat, 16 Aug 2003 01:57:55 +0200, "olivier fourcade"
wrote:

Quelqu'un a t'il une solution


Deux solutions :

1/ Lancer une exception
2/ Mettre une indicateur booleen "ok" à "false", et demander à
l'utilisateur de tester la validité de l'objet après construction.


3/ Créer une fonction membre statique:

class Toto
{
public:
static Toto* Create(int param); // fait le test
private:
Toto(int param);
};

C'est sur qu'après le fonctionnement n'est pas le même (ne marchera pas
avec les fonctions s'attendant à alloue avec "new").


Avatar
Patrick Mézard
Quelqu'un a t'il une solution


Deux solutions :

1/ Lancer une exception
2/ Mettre une indicateur booleen "ok" à "false", et demander à
l'utilisateur de tester la validité de l'objet après construction.


3/ Créer une fonction membre statique:

class Toto
{
public:
static Toto* Create(int param); // fait le test
private:
Toto(int param);
};


Je ne comprends pas trop ce que ça apporte. Tu l'écris comment ta fonction
statique ? Comme ça :

Toto* Toto::Create(int param)
{
try
{
Toto* t = new Toto(int);
//Et là ?
if(!t->ok())
{
delete t;
t = 0;
}
return t;
}
catch(std::bad_alloc& e)
{
return 0;
}
}

Si c'est ça, ça revient à encapsuler l'appel de Toto::ok(), histoire de ne
pas l'oublier. Dans ce cas, je préfère balancer une exception, si le mec
l'oublie, c'est std::terminate et basta. Mais j'ai peut-être mal compris ce
que tu voulais dire.


C'est sur qu'après le fonctionnement n'est pas le même (ne marchera pas
avec les fonctions s'attendant à alloue avec "new").


Pas forcément, dans le même genre on peut renvoyer l'objet par copie (si
c'est possible), mais bon c'est pas forcément hyper efficace.

Patrick Mézard



Avatar
Fabien SK
Patrick Mézard wrote:
Quelqu'un a t'il une solution


Deux solutions :

1/ Lancer une exception
2/ Mettre une indicateur booleen "ok" à "false", et demander à
l'utilisateur de tester la validité de l'objet après construction.


3/ Créer une fonction membre statique:

class Toto
{
public:
static Toto* Create(int param); // fait le test
private:
Toto(int param);
};



Je ne comprends pas trop ce que ça apporte. Tu l'écris comment ta fonction
statique ? Comme ça :


Au temps pour moi (et pour le délai):

Toto* Toto::Create(int param1, param2)
{
// verifie si les parametres sont valides pour construire un "Toto*"
if (param1>5 && param2!=2)
return new Toto(param1, param2);
else
return 0;
}

Ca te permet de retourner NULL si les conditions d'entree ne sont pas
réunies. Par contre, ça ne répond pas à ton problème si l'initialisation
d'un membre échoue. Exemple:

Toto::Toto(const char *filename)
{
m_File.open(filename);
if (m_File.is_open()=úlse)
{
// ne peut pas être construit
}
}

On ne peut pas faire de test dans "Create", à moins que "Create" passe
au constructeur de "Toto" un "std::ifstream*" déjà initialisé, mais ça
peut être lourd (de passer tous les membres initialisés).

Fabien