j'ai un constructeur prenant un paramètre, est-il possible dans le
corps du constructeur de tester le paramètre et de faire échouer la
construction de l'objet après le test ? ou doit-on se contenter de
tester le paramètre avant d'appeler de constructeur (ce qui n'est pas
top du tout)
j'ai un constructeur prenant un paramètre, est-il possible dans le corps du constructeur de tester le paramètre et de faire échouer la construction de l'objet après le test ? ou doit-on se contenter de tester le paramètre avant d'appeler de constructeur (ce qui n'est pas top du tout)
je pense aux exceptions... mais bon...
ben oui je vois pas trop quoi faire d'autre. Si une exception est lancée dans un constructeur, l'objet n'est je crois pas construit.
MonObj::MonObj(Mon Par) { if( MonPar est pas bon) throw UneExceptionAMoiQueJAime; ContinueAConstruire(); }
"Nicolas Aunai" <nicolas.aunai@free.fr> a écrit dans le message de
news:mesnews.6ca17d42.00ff7bdd.125.1437@free.fr...
salut,
j'ai un constructeur prenant un paramètre, est-il possible dans le
corps du constructeur de tester le paramètre et de faire échouer la
construction de l'objet après le test ? ou doit-on se contenter de
tester le paramètre avant d'appeler de constructeur (ce qui n'est pas
top du tout)
je pense aux exceptions... mais bon...
ben oui je vois pas trop quoi faire d'autre. Si une exception est lancée
dans un constructeur, l'objet n'est je crois pas construit.
MonObj::MonObj(Mon Par)
{
if( MonPar est pas bon)
throw UneExceptionAMoiQueJAime;
ContinueAConstruire();
}
j'ai un constructeur prenant un paramètre, est-il possible dans le corps du constructeur de tester le paramètre et de faire échouer la construction de l'objet après le test ? ou doit-on se contenter de tester le paramètre avant d'appeler de constructeur (ce qui n'est pas top du tout)
je pense aux exceptions... mais bon...
ben oui je vois pas trop quoi faire d'autre. Si une exception est lancée dans un constructeur, l'objet n'est je crois pas construit.
MonObj::MonObj(Mon Par) { if( MonPar est pas bon) throw UneExceptionAMoiQueJAime; ContinueAConstruire(); }
j'ai un constructeur prenant un paramètre, est-il possible dans le corps du constructeur de tester le paramètre et de faire échouer la construction de l'objet après le test ? ou doit-on se contenter de tester le paramètre avant d'appeler de constructeur (ce qui n'est pas top du tout)
je pense aux exceptions... mais bon...
Exactement. http://www.gotw.ca/gotw/066.htm ("Constructor Failures") est intéressant à ce sujet.
Patrick Mézard
j'ai un constructeur prenant un paramètre, est-il possible dans le
corps du constructeur de tester le paramètre et de faire échouer la
construction de l'objet après le test ? ou doit-on se contenter de
tester le paramètre avant d'appeler de constructeur (ce qui n'est pas
top du tout)
je pense aux exceptions... mais bon...
Exactement.
http://www.gotw.ca/gotw/066.htm ("Constructor Failures") est intéressant à
ce sujet.
j'ai un constructeur prenant un paramètre, est-il possible dans le corps du constructeur de tester le paramètre et de faire échouer la construction de l'objet après le test ? ou doit-on se contenter de tester le paramètre avant d'appeler de constructeur (ce qui n'est pas top du tout)
je pense aux exceptions... mais bon...
Exactement. http://www.gotw.ca/gotw/066.htm ("Constructor Failures") est intéressant à ce sujet.
Patrick Mézard
Nicolas Aunai
Patrick Mézard avait écrit le 14/02/2004 :
Exactement. http://www.gotw.ca/gotw/066.htm ("Constructor Failures") est intéressant à ce sujet.
ok merci des renseignements.
concernant les exceptions, lorsqu'on fait un projet, à quel moment doit-on commencer la réflexion sur les classes d'exceptions, leur hierarchie, organisation etc... doit-on s'en préoccuper dès l'étape de conception, pendant le codage a proprement parler, ou plutot une fois que tout est fait, on s'occupe de la gestion des exceptions ?
Exactement.
http://www.gotw.ca/gotw/066.htm ("Constructor Failures") est intéressant à
ce sujet.
ok merci des renseignements.
concernant les exceptions, lorsqu'on fait un projet, à quel moment
doit-on commencer la réflexion sur les classes d'exceptions, leur
hierarchie, organisation etc... doit-on s'en préoccuper dès l'étape de
conception, pendant le codage a proprement parler, ou plutot une fois
que tout est fait, on s'occupe de la gestion des exceptions ?
Exactement. http://www.gotw.ca/gotw/066.htm ("Constructor Failures") est intéressant à ce sujet.
ok merci des renseignements.
concernant les exceptions, lorsqu'on fait un projet, à quel moment doit-on commencer la réflexion sur les classes d'exceptions, leur hierarchie, organisation etc... doit-on s'en préoccuper dès l'étape de conception, pendant le codage a proprement parler, ou plutot une fois que tout est fait, on s'occupe de la gestion des exceptions ?
j'ai un constructeur prenant un paramètre, est-il possible dans le corps du constructeur de tester le paramètre et de faire échouer la construction de l'objet après le test ?
Moi, je ferais une fonction statique que tu appelles à la place du constructeur, qui renvoit un objet de ta classe, et qui ne fait le "new" que si le test réussi.
Parce que si tu le fait dans le constructeur, le "malloc" est déjà fait, c'est moins efficace.
-- Matthieu
Nicolas Aunai <nicolas.aunai@free.fr> writes:
salut,
j'ai un constructeur prenant un paramètre, est-il possible dans le
corps du constructeur de tester le paramètre et de faire échouer la
construction de l'objet après le test ?
Moi, je ferais une fonction statique que tu appelles à la place du
constructeur, qui renvoit un objet de ta classe, et qui ne fait le
"new" que si le test réussi.
Parce que si tu le fait dans le constructeur, le "malloc" est déjà
fait, c'est moins efficace.
j'ai un constructeur prenant un paramètre, est-il possible dans le corps du constructeur de tester le paramètre et de faire échouer la construction de l'objet après le test ?
Moi, je ferais une fonction statique que tu appelles à la place du constructeur, qui renvoit un objet de ta classe, et qui ne fait le "new" que si le test réussi.
Parce que si tu le fait dans le constructeur, le "malloc" est déjà fait, c'est moins efficace.
-- Matthieu
Patrick Mézard
salut,
j'ai un constructeur prenant un paramètre, est-il possible dans le corps du constructeur de tester le paramètre et de faire échouer la construction de l'objet après le test ?
Moi, je ferais une fonction statique que tu appelles à la place du constructeur, qui renvoit un objet de ta classe, et qui ne fait le "new" que si le test réussi.
De quel new parles-tu ? Comment ferais-tu lorsque l'objet n'est pas instancié dynamiquement comme là :
struct array { array(int size) { if(size<0) throw std::invalid_argument("Size must be positive"); [...] //Alloue le tableau et fait des trucs }
[...] }
int main() { array a(-1); }
Parce que si tu le fait dans le constructeur, le "malloc" est déjà fait, c'est moins efficace.
De quel malloc parles-tu ?
Patrick Mézard
salut,
j'ai un constructeur prenant un paramètre, est-il possible dans le
corps du constructeur de tester le paramètre et de faire échouer la
construction de l'objet après le test ?
Moi, je ferais une fonction statique que tu appelles à la place du
constructeur, qui renvoit un objet de ta classe, et qui ne fait le
"new" que si le test réussi.
De quel new parles-tu ?
Comment ferais-tu lorsque l'objet n'est pas instancié dynamiquement comme là
:
struct array
{
array(int size)
{
if(size<0)
throw std::invalid_argument("Size must be positive");
[...]
//Alloue le tableau et fait des trucs
}
[...]
}
int main()
{
array a(-1);
}
Parce que si tu le fait dans le constructeur, le "malloc" est déjà
fait, c'est moins efficace.
j'ai un constructeur prenant un paramètre, est-il possible dans le corps du constructeur de tester le paramètre et de faire échouer la construction de l'objet après le test ?
Moi, je ferais une fonction statique que tu appelles à la place du constructeur, qui renvoit un objet de ta classe, et qui ne fait le "new" que si le test réussi.
De quel new parles-tu ? Comment ferais-tu lorsque l'objet n'est pas instancié dynamiquement comme là :
struct array { array(int size) { if(size<0) throw std::invalid_argument("Size must be positive"); [...] //Alloue le tableau et fait des trucs }
[...] }
int main() { array a(-1); }
Parce que si tu le fait dans le constructeur, le "malloc" est déjà fait, c'est moins efficace.
De quel malloc parles-tu ?
Patrick Mézard
Patrick Mézard
Exactement. http://www.gotw.ca/gotw/066.htm ("Constructor Failures") est intéressant à
ce sujet.
ok merci des renseignements.
concernant les exceptions, lorsqu'on fait un projet, à quel moment doit-on commencer la réflexion sur les classes d'exceptions, leur hierarchie, organisation etc... doit-on s'en préoccuper dès l'étape de conception, pendant le codage a proprement parler, ou plutot une fois que tout est fait, on s'occupe de la gestion des exceptions ?
Ca dépend de ce que tu entends par "gestion des exceptions". A partir du moment où tu admets que ton code va voir passer des exceptions, il vaut mieux en tenir compte partout, ça évite les mauvaises surprises. Ca veut dire de gèrer les ressources correctement avec de la RAII, d'établir et de conserver tes invariants d'objets même et surtout en cas d'exceptions, etc...
En ce qui concerne la manière d'organiser et de gèrer tes exceptions, c'est au cas par cas. Dans le cas d'une bibliothèque très spécialisée (compression d'image par exemple) on peut imaginer qu'une seule classe d'exception contenant un code d'erreur soit suffisante, car le traitement de l'exception sera lui aussi sommaire (est-ce que j'ai réussi à compresser ou pas, si non, pourquoi, et ça s'arrête là). Maintenant, si les traitements sont plus complexes, la hiérarchie d'exceptions sera à leur image. Mais dans ce cas, cette hiérarchie se dessinera d'elle-même avec le reste du code, vu qu'elle apportera des fonctionnalités au même titre que les autres classes. La gestion d'erreur n'est pas quelque chose d'anodin, en marge du processus de développement. Il me parait difficile de s'en occuper a posteriori.
Patrick Mézard
Exactement.
http://www.gotw.ca/gotw/066.htm ("Constructor Failures") est intéressant
à
ce sujet.
ok merci des renseignements.
concernant les exceptions, lorsqu'on fait un projet, à quel moment
doit-on commencer la réflexion sur les classes d'exceptions, leur
hierarchie, organisation etc... doit-on s'en préoccuper dès l'étape de
conception, pendant le codage a proprement parler, ou plutot une fois
que tout est fait, on s'occupe de la gestion des exceptions ?
Ca dépend de ce que tu entends par "gestion des exceptions".
A partir du moment où tu admets que ton code va voir passer des exceptions,
il vaut mieux en tenir compte partout, ça évite les mauvaises surprises. Ca
veut dire de gèrer les ressources correctement avec de la RAII, d'établir et
de conserver tes invariants d'objets même et surtout en cas d'exceptions,
etc...
En ce qui concerne la manière d'organiser et de gèrer tes exceptions, c'est
au cas par cas. Dans le cas d'une bibliothèque très spécialisée (compression
d'image par exemple) on peut imaginer qu'une seule classe d'exception
contenant un code d'erreur soit suffisante, car le traitement de l'exception
sera lui aussi sommaire (est-ce que j'ai réussi à compresser ou pas, si non,
pourquoi, et ça s'arrête là). Maintenant, si les traitements sont plus
complexes, la hiérarchie d'exceptions sera à leur image. Mais dans ce cas,
cette hiérarchie se dessinera d'elle-même avec le reste du code, vu qu'elle
apportera des fonctionnalités au même titre que les autres classes. La
gestion d'erreur n'est pas quelque chose d'anodin, en marge du processus de
développement. Il me parait difficile de s'en occuper a posteriori.
Exactement. http://www.gotw.ca/gotw/066.htm ("Constructor Failures") est intéressant à
ce sujet.
ok merci des renseignements.
concernant les exceptions, lorsqu'on fait un projet, à quel moment doit-on commencer la réflexion sur les classes d'exceptions, leur hierarchie, organisation etc... doit-on s'en préoccuper dès l'étape de conception, pendant le codage a proprement parler, ou plutot une fois que tout est fait, on s'occupe de la gestion des exceptions ?
Ca dépend de ce que tu entends par "gestion des exceptions". A partir du moment où tu admets que ton code va voir passer des exceptions, il vaut mieux en tenir compte partout, ça évite les mauvaises surprises. Ca veut dire de gèrer les ressources correctement avec de la RAII, d'établir et de conserver tes invariants d'objets même et surtout en cas d'exceptions, etc...
En ce qui concerne la manière d'organiser et de gèrer tes exceptions, c'est au cas par cas. Dans le cas d'une bibliothèque très spécialisée (compression d'image par exemple) on peut imaginer qu'une seule classe d'exception contenant un code d'erreur soit suffisante, car le traitement de l'exception sera lui aussi sommaire (est-ce que j'ai réussi à compresser ou pas, si non, pourquoi, et ça s'arrête là). Maintenant, si les traitements sont plus complexes, la hiérarchie d'exceptions sera à leur image. Mais dans ce cas, cette hiérarchie se dessinera d'elle-même avec le reste du code, vu qu'elle apportera des fonctionnalités au même titre que les autres classes. La gestion d'erreur n'est pas quelque chose d'anodin, en marge du processus de développement. Il me parait difficile de s'en occuper a posteriori.
Patrick Mézard
Vladimir
j'ai un constructeur prenant un paramètre, est-il possible dans le corps du constructeur de tester le paramètre et de faire échouer la construction de l'objet après le test ? ou doit-on se contenter de tester le paramètre avant d'appeler de constructeur (ce qui n'est pas top du tout)
je pense aux exceptions... mais bon...
Le plus élégant serait de lancer une exception lors de la construction,
sinon une autre solution est de faire un delete this ( c'est pas très élégant, mais ça peut parfaitement convenir dans certain cas .... )
j'ai un constructeur prenant un paramètre, est-il possible dans le
corps du constructeur de tester le paramètre et de faire échouer la
construction de l'objet après le test ? ou doit-on se contenter de
tester le paramètre avant d'appeler de constructeur (ce qui n'est pas
top du tout)
je pense aux exceptions... mais bon...
Le plus élégant serait de lancer une exception lors de la construction,
sinon une autre solution est de faire un delete this ( c'est pas très
élégant, mais ça peut parfaitement convenir dans certain cas .... )
j'ai un constructeur prenant un paramètre, est-il possible dans le corps du constructeur de tester le paramètre et de faire échouer la construction de l'objet après le test ? ou doit-on se contenter de tester le paramètre avant d'appeler de constructeur (ce qui n'est pas top du tout)
je pense aux exceptions... mais bon...
Le plus élégant serait de lancer une exception lors de la construction,
sinon une autre solution est de faire un delete this ( c'est pas très élégant, mais ça peut parfaitement convenir dans certain cas .... )
Matthieu Moy
"Patrick Mézard" writes:
De quel new parles-tu ?
Du "new" que tu fais si tu alloue l'objet dynamiquement.
Comment ferais-tu lorsque l'objet n'est pas instancié dynamiquement comme là
[...]
int main() { array a(-1); }
En effet, dans ce cas là, tu ne peux pas passer à coté de l'appel du constructeur. Mais à ce moment là, je ne vois pas trop quelle sémantique on peut donner à « faire échouer la construction de l'objet ». Si tu peux écrire
array a(-1); b = a;
Alors, quelle est la sémantique de « b = a » ?
Effectivement, avec des exceptions, on s'en sort, puisque la ligne « b = a » n'est plus atteignable, mais à ce moment, c'est plus que la création de l'objet qui échoue, c'est carrément tout le bloc d'instruction qui utilise l'objet. (Mais ça répond peut être à la question, je ne dis pas le contraire)
Reste à voir ce que voulais exactement le posteur original ...
Du "new" que tu fais si tu alloue l'objet dynamiquement.
Comment ferais-tu lorsque l'objet n'est pas instancié dynamiquement comme là
[...]
int main() {
array a(-1);
}
En effet, dans ce cas là, tu ne peux pas passer à coté de l'appel du
constructeur. Mais à ce moment là, je ne vois pas trop quelle
sémantique on peut donner à « faire échouer la construction de
l'objet ». Si tu peux écrire
array a(-1);
b = a;
Alors, quelle est la sémantique de « b = a » ?
Effectivement, avec des exceptions, on s'en sort, puisque la ligne « b
= a » n'est plus atteignable, mais à ce moment, c'est plus que la
création de l'objet qui échoue, c'est carrément tout le bloc
d'instruction qui utilise l'objet. (Mais ça répond peut être à la
question, je ne dis pas le contraire)
Reste à voir ce que voulais exactement le posteur original ...
Du "new" que tu fais si tu alloue l'objet dynamiquement.
Comment ferais-tu lorsque l'objet n'est pas instancié dynamiquement comme là
[...]
int main() { array a(-1); }
En effet, dans ce cas là, tu ne peux pas passer à coté de l'appel du constructeur. Mais à ce moment là, je ne vois pas trop quelle sémantique on peut donner à « faire échouer la construction de l'objet ». Si tu peux écrire
array a(-1); b = a;
Alors, quelle est la sémantique de « b = a » ?
Effectivement, avec des exceptions, on s'en sort, puisque la ligne « b = a » n'est plus atteignable, mais à ce moment, c'est plus que la création de l'objet qui échoue, c'est carrément tout le bloc d'instruction qui utilise l'objet. (Mais ça répond peut être à la question, je ne dis pas le contraire)
Reste à voir ce que voulais exactement le posteur original ...
-- Matthieu
Patrick Mézard
int main() { array a(-1); }
En effet, dans ce cas là, tu ne peux pas passer à coté de l'appel du constructeur. Mais à ce moment là, je ne vois pas trop quelle sémantique on peut donner à « faire échouer la construction de l'objet ».
C'est exactement le sujet du "Guru of the Week" cité dans ma première réponse : un objet non construit n'existe pas, donc on ne peut pas l'utiliser. C'est pourquoi le fameux idiome du "constructeur + init()" dénoncé par Stroustrup dans TCPPL est moins robuste que l'utilisation d'exceptions pour signaler des échecs de constructions.
Si tu peux écrire
array a(-1); b = a;
Alors, quelle est la sémantique de « b = a » ?
Aucune. Cette instruction n'a de sens que si "a" est valide (ie. les invariants d'objets sont valides). En cas d'échec à la construction de "a", il ne peuvent l'être par définition.
Effectivement, avec des exceptions, on s'en sort, puisque la ligne « b = a » n'est plus atteignable, mais à ce moment, c'est plus que la création de l'objet qui échoue, c'est carrément tout le bloc d'instruction qui utilise l'objet. (Mais ça répond peut être à la question, je ne dis pas le contraire)
Reste à voir ce que voulais exactement le posteur original ...
Disons que je ne vois pas d'autre alternative. La technique du genre "j'instancie une version incomplète mais destructible de l'objet, puis je tente de l'initialiser et fait un return en cas d'échec" n'est pas fondamentalement différente d'une levée d'exception. Elle est juste plus complexe et plus fragile.
Patrick Mézard
int main() {
array a(-1);
}
En effet, dans ce cas là, tu ne peux pas passer à coté de l'appel du
constructeur. Mais à ce moment là, je ne vois pas trop quelle
sémantique on peut donner à « faire échouer la construction de
l'objet ».
C'est exactement le sujet du "Guru of the Week" cité dans ma première
réponse : un objet non construit n'existe pas, donc on ne peut pas
l'utiliser. C'est pourquoi le fameux idiome du "constructeur + init()"
dénoncé par Stroustrup dans TCPPL est moins robuste que l'utilisation
d'exceptions pour signaler des échecs de constructions.
Si tu peux écrire
array a(-1);
b = a;
Alors, quelle est la sémantique de « b = a » ?
Aucune. Cette instruction n'a de sens que si "a" est valide (ie. les
invariants d'objets sont valides). En cas d'échec à la construction de "a",
il ne peuvent l'être par définition.
Effectivement, avec des exceptions, on s'en sort, puisque la ligne « b
= a » n'est plus atteignable, mais à ce moment, c'est plus que la
création de l'objet qui échoue, c'est carrément tout le bloc
d'instruction qui utilise l'objet. (Mais ça répond peut être à la
question, je ne dis pas le contraire)
Reste à voir ce que voulais exactement le posteur original ...
Disons que je ne vois pas d'autre alternative. La technique du genre
"j'instancie une version incomplète mais destructible de l'objet, puis je
tente de l'initialiser et fait un return en cas d'échec" n'est pas
fondamentalement différente d'une levée d'exception. Elle est juste plus
complexe et plus fragile.
En effet, dans ce cas là, tu ne peux pas passer à coté de l'appel du constructeur. Mais à ce moment là, je ne vois pas trop quelle sémantique on peut donner à « faire échouer la construction de l'objet ».
C'est exactement le sujet du "Guru of the Week" cité dans ma première réponse : un objet non construit n'existe pas, donc on ne peut pas l'utiliser. C'est pourquoi le fameux idiome du "constructeur + init()" dénoncé par Stroustrup dans TCPPL est moins robuste que l'utilisation d'exceptions pour signaler des échecs de constructions.
Si tu peux écrire
array a(-1); b = a;
Alors, quelle est la sémantique de « b = a » ?
Aucune. Cette instruction n'a de sens que si "a" est valide (ie. les invariants d'objets sont valides). En cas d'échec à la construction de "a", il ne peuvent l'être par définition.
Effectivement, avec des exceptions, on s'en sort, puisque la ligne « b = a » n'est plus atteignable, mais à ce moment, c'est plus que la création de l'objet qui échoue, c'est carrément tout le bloc d'instruction qui utilise l'objet. (Mais ça répond peut être à la question, je ne dis pas le contraire)
Reste à voir ce que voulais exactement le posteur original ...
Disons que je ne vois pas d'autre alternative. La technique du genre "j'instancie une version incomplète mais destructible de l'objet, puis je tente de l'initialiser et fait un return en cas d'échec" n'est pas fondamentalement différente d'une levée d'exception. Elle est juste plus complexe et plus fragile.