Un doute existenciel a propos du parcours de liste dans une boucle 'for'
79 réponses
meow
> for ( iterator it=3Dliste.begin() ; it!=3Dliste.end() ; ++it )
Question =E0 deux balles : A tous les coups, le compilo n'a aucun moyen
d'extraire la valeur de liste.end() une fois pour toute avant le d=E9but
de la boucle, du coup =E0 chaque it=E9ration de la boucle le programme se
retape l'appel =E0 liste.end() !
La question toute simple que je me pose est donc : est-ce que c'est pas
mieux de faire
Tout code supplémentaire introduit un risque d'erreur.
Du code oui. Mais là il s'agit juste d'une variable au sujet de laquelle personne ne se méprendra.
Certes. Mais moi, au moins, je ne me sens jamais à l'abri d'une faute de frappe. Ce n'est pas une grande risque, et je n'hésite pas d'ajouter une variable s'il rend le code plus clair. Mais ici, il me semble une variable en plus.
Il y a aussi la question de l'utilisation des idiomes standards. Dans la mesure où le code correspond exactement à un idiome standard, on le reconnaît, et on se sent comfortable avec lui. (Évidement, ce qui constitue un idiome standard évolve. Mais s'il y a évolution à cet égard, je préfèrerais la version de Fabien, avec une seule déclaration, dans le for.)
[...]
C'est tout l'univers de C++ ça la diversité ;) Moi c'est quand il dit que le test d'auto-affectation ne devrait pas être nécessaire pour un operator= que je ne partage pas son avis.
Tiens, tiens, tiens. C'est moi qui lui a soufflé cette idée:-).
Montre-moi une exception. Un cas où il est nécessaire.
Je trouve qu'il s'inquiète bien trop de la performance, trop tôt.
C'est vrai que c'est un travers dans lequel il ne faut pas tomber. Là je suis bien d'accord avec toi. C'est juste qu'à mon avis à la variable supplémentaire pour end(), ce n'est pas porteur de problèmes potentie ls. enfin AMHA.
C'est sûr que ce n'est pas la fin du monde. Et qu'il y en a pire, bien pire.
Je préfère toujours le code plus facile à maintenir. Ce qui veut dire, sans variables supplémentaires.
D'accord, mais dans notre cas toujours, je ne vois pas bien le problème de maintenance.
Et je constate par expérience que mon code est plus qu'assez vite.
Je dois aussi confesser que pour mon malheur je fait beaucoup de Java et c'est en codant des boucles sur des tableaux en Java que j'ais pris l'habitude de sortir tableau.length de la boucle. Et je me suis mis à faire l'équivalent en C++
Marrant. En Java, je me servais aussi des itérateurs. Et du coup, la question ne se posait pas, parce qu'avec un itérateur Java, un suffit.
-- James Kanze GABI Software 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
Alain Gaillard wrote:
[...]
Tout code supplémentaire introduit un risque d'erreur.
Du code oui. Mais là il s'agit juste d'une variable au sujet
de laquelle personne ne se méprendra.
Certes. Mais moi, au moins, je ne me sens jamais à l'abri d'une
faute de frappe. Ce n'est pas une grande risque, et je n'hésite
pas d'ajouter une variable s'il rend le code plus clair. Mais
ici, il me semble une variable en plus.
Il y a aussi la question de l'utilisation des idiomes standards.
Dans la mesure où le code correspond exactement à un idiome
standard, on le reconnaît, et on se sent comfortable avec lui.
(Évidement, ce qui constitue un idiome standard évolve. Mais
s'il y a évolution à cet égard, je préfèrerais la version de
Fabien, avec une seule déclaration, dans le for.)
[...]
C'est tout l'univers de C++ ça la diversité ;)
Moi c'est quand il dit que le test d'auto-affectation ne devrait pas
être nécessaire pour un operator= que je ne partage pas son avis.
Tiens, tiens, tiens. C'est moi qui lui a soufflé cette idée:-).
Montre-moi une exception. Un cas où il est nécessaire.
Je
trouve qu'il s'inquiète bien trop de la performance, trop tôt.
C'est vrai que c'est un travers dans lequel il ne faut pas tomber. Là je
suis bien d'accord avec toi. C'est juste qu'à mon avis à la variable
supplémentaire pour end(), ce n'est pas porteur de problèmes potentie ls.
enfin AMHA.
C'est sûr que ce n'est pas la fin du monde. Et qu'il y en a
pire, bien pire.
Je préfère toujours le code plus facile à maintenir. Ce qui veut
dire, sans variables supplémentaires.
D'accord, mais dans notre cas toujours, je ne vois pas bien le problème
de maintenance.
Et je constate par expérience que mon code est plus qu'assez
vite.
Je dois aussi confesser que pour mon malheur je fait beaucoup
de Java et c'est en codant des boucles sur des tableaux en
Java que j'ais pris l'habitude de sortir tableau.length de la
boucle. Et je me suis mis à faire l'équivalent en C++
Marrant. En Java, je me servais aussi des itérateurs. Et du
coup, la question ne se posait pas, parce qu'avec un itérateur
Java, un suffit.
--
James Kanze GABI Software
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
Tout code supplémentaire introduit un risque d'erreur.
Du code oui. Mais là il s'agit juste d'une variable au sujet de laquelle personne ne se méprendra.
Certes. Mais moi, au moins, je ne me sens jamais à l'abri d'une faute de frappe. Ce n'est pas une grande risque, et je n'hésite pas d'ajouter une variable s'il rend le code plus clair. Mais ici, il me semble une variable en plus.
Il y a aussi la question de l'utilisation des idiomes standards. Dans la mesure où le code correspond exactement à un idiome standard, on le reconnaît, et on se sent comfortable avec lui. (Évidement, ce qui constitue un idiome standard évolve. Mais s'il y a évolution à cet égard, je préfèrerais la version de Fabien, avec une seule déclaration, dans le for.)
[...]
C'est tout l'univers de C++ ça la diversité ;) Moi c'est quand il dit que le test d'auto-affectation ne devrait pas être nécessaire pour un operator= que je ne partage pas son avis.
Tiens, tiens, tiens. C'est moi qui lui a soufflé cette idée:-).
Montre-moi une exception. Un cas où il est nécessaire.
Je trouve qu'il s'inquiète bien trop de la performance, trop tôt.
C'est vrai que c'est un travers dans lequel il ne faut pas tomber. Là je suis bien d'accord avec toi. C'est juste qu'à mon avis à la variable supplémentaire pour end(), ce n'est pas porteur de problèmes potentie ls. enfin AMHA.
C'est sûr que ce n'est pas la fin du monde. Et qu'il y en a pire, bien pire.
Je préfère toujours le code plus facile à maintenir. Ce qui veut dire, sans variables supplémentaires.
D'accord, mais dans notre cas toujours, je ne vois pas bien le problème de maintenance.
Et je constate par expérience que mon code est plus qu'assez vite.
Je dois aussi confesser que pour mon malheur je fait beaucoup de Java et c'est en codant des boucles sur des tableaux en Java que j'ais pris l'habitude de sortir tableau.length de la boucle. Et je me suis mis à faire l'équivalent en C++
Marrant. En Java, je me servais aussi des itérateurs. Et du coup, la question ne se posait pas, parce qu'avec un itérateur Java, un suffit.
-- James Kanze GABI Software 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
Alain Gaillard wrote:
Tiens ? Tu as un contre-exemple ?
Que veux tu dire par contre exemple ?
Si j'écris une classe qui définit l'opérator =, l'auto-affectation je la teste systématiquement. Se contenter de retourner *this au lieu d'exécuter plein de code me paraît tellement naturel.
Le test coûte quand même du temps. En plus du temps qu'il te faut autrement, s'il n'y a pas identité. Moi, je partirais plutôt de l'idée que les auto-affectations sont des cas assez rares, et je n'ajouterais pas du code pour les optimiser s'il rallentissait aussi peu soit-il le cas où les objets n'étaient pas identiques.
-- James Kanze GABI Software 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
Alain Gaillard wrote:
Tiens ? Tu as un contre-exemple ?
Que veux tu dire par contre exemple ?
Si j'écris une classe qui définit l'opérator =,
l'auto-affectation je la teste systématiquement. Se contenter
de retourner *this au lieu d'exécuter plein de code me paraît
tellement naturel.
Le test coûte quand même du temps. En plus du temps qu'il te
faut autrement, s'il n'y a pas identité. Moi, je partirais
plutôt de l'idée que les auto-affectations sont des cas assez
rares, et je n'ajouterais pas du code pour les optimiser s'il
rallentissait aussi peu soit-il le cas où les objets n'étaient
pas identiques.
--
James Kanze GABI Software
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
Si j'écris une classe qui définit l'opérator =, l'auto-affectation je la teste systématiquement. Se contenter de retourner *this au lieu d'exécuter plein de code me paraît tellement naturel.
Le test coûte quand même du temps. En plus du temps qu'il te faut autrement, s'il n'y a pas identité. Moi, je partirais plutôt de l'idée que les auto-affectations sont des cas assez rares, et je n'ajouterais pas du code pour les optimiser s'il rallentissait aussi peu soit-il le cas où les objets n'étaient pas identiques.
-- James Kanze GABI Software 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
Alain Gaillard
Le test coûte quand même du temps. En plus du temps qu'il te faut autrement, s'il n'y a pas identité.
Certes, mais quand même là, ça ne coûte pas cher. Sûrement moins qu'un end() invoqué à tout bouts de champs si je peux me permettre.
Moi, je partirais plutôt de l'idée que les auto-affectations sont des cas assez rares,
Oui c'est vrai aussi ça.
-- Alain
Le test coûte quand même du temps. En plus du temps qu'il te
faut autrement, s'il n'y a pas identité.
Certes, mais quand même là, ça ne coûte pas cher.
Sûrement moins qu'un end() invoqué à tout bouts de champs si je peux me
permettre.
Moi, je partirais
plutôt de l'idée que les auto-affectations sont des cas assez
rares,
Le test coûte quand même du temps. En plus du temps qu'il te faut autrement, s'il n'y a pas identité.
Certes, mais quand même là, ça ne coûte pas cher. Sûrement moins qu'un end() invoqué à tout bouts de champs si je peux me permettre.
Moi, je partirais plutôt de l'idée que les auto-affectations sont des cas assez rares,
Oui c'est vrai aussi ça.
-- Alain
Alain Gaillard
(Évidement, ce qui constitue un idiome standard évolve. Mais s'il y a évolution à cet égard, je préfèrerais la version de Fabien, avec une seule déclaration, dans le for.)
Ah mais oui. Moi je n'ai jamais dit le contraire. Ce n'est pas moi qui a proposé:
Et comme Fabien à proposé tout de suite sa version je n'ai pas vu l'intérêt d'insister. Ce que je dis simplement c'est que comme ça on évite de construire n fois un objet. Bien sûr que la version de Fabien est meilleure, mais au niveau de l'élégance du code seulement. Tu as quand même toujours une variable supplémentaire et la construction de l'itérateur qui est sortie de la boucle.
Tiens, tiens, tiens. C'est moi qui lui a soufflé cette idée:-).
LOL, le monde est petit.
Je dois aussi confesser que pour mon malheur je fait beaucoup de Java et c'est en codant des boucles sur des tableaux en Java que j'ais pris l'habitude de sortir tableau.length de la boucle. Et je me suis mis à faire l'équivalent en C++
Marrant. En Java, je me servais aussi des itérateurs. Et du coup, la question ne se posait pas, parce qu'avec un itérateur Java, un suffit.
Avec des containers, pas avec des tableaux. Et la question des perfs avec les conteneurs, et les transtypages permanents que ça implique. Bouh... revenons au bon vieux C++ :)
-- Alain
(Évidement, ce qui constitue un idiome standard évolve. Mais
s'il y a évolution à cet égard, je préfèrerais la version de
Fabien, avec une seule déclaration, dans le for.)
Ah mais oui. Moi je n'ai jamais dit le contraire. Ce n'est pas moi qui a
proposé:
Et comme Fabien à proposé tout de suite sa version je n'ai pas vu
l'intérêt d'insister.
Ce que je dis simplement c'est que comme ça on évite de construire n
fois un objet. Bien sûr que la version de Fabien est meilleure, mais au
niveau de l'élégance du code seulement. Tu as quand même toujours une
variable supplémentaire et la construction de l'itérateur qui est sortie
de la boucle.
Tiens, tiens, tiens. C'est moi qui lui a soufflé cette idée:-).
LOL, le monde est petit.
Je dois aussi confesser que pour mon malheur je fait beaucoup
de Java et c'est en codant des boucles sur des tableaux en
Java que j'ais pris l'habitude de sortir tableau.length de la
boucle. Et je me suis mis à faire l'équivalent en C++
Marrant. En Java, je me servais aussi des itérateurs. Et du
coup, la question ne se posait pas, parce qu'avec un itérateur
Java, un suffit.
Avec des containers, pas avec des tableaux.
Et la question des perfs avec les conteneurs, et les transtypages
permanents que ça implique. Bouh... revenons au bon vieux C++ :)
(Évidement, ce qui constitue un idiome standard évolve. Mais s'il y a évolution à cet égard, je préfèrerais la version de Fabien, avec une seule déclaration, dans le for.)
Ah mais oui. Moi je n'ai jamais dit le contraire. Ce n'est pas moi qui a proposé:
Et comme Fabien à proposé tout de suite sa version je n'ai pas vu l'intérêt d'insister. Ce que je dis simplement c'est que comme ça on évite de construire n fois un objet. Bien sûr que la version de Fabien est meilleure, mais au niveau de l'élégance du code seulement. Tu as quand même toujours une variable supplémentaire et la construction de l'itérateur qui est sortie de la boucle.
Tiens, tiens, tiens. C'est moi qui lui a soufflé cette idée:-).
LOL, le monde est petit.
Je dois aussi confesser que pour mon malheur je fait beaucoup de Java et c'est en codant des boucles sur des tableaux en Java que j'ais pris l'habitude de sortir tableau.length de la boucle. Et je me suis mis à faire l'équivalent en C++
Marrant. En Java, je me servais aussi des itérateurs. Et du coup, la question ne se posait pas, parce qu'avec un itérateur Java, un suffit.
Avec des containers, pas avec des tableaux. Et la question des perfs avec les conteneurs, et les transtypages permanents que ça implique. Bouh... revenons au bon vieux C++ :)
-- Alain
Fabien LE LEZ
On Fri, 22 Sep 2006 18:08:38 +0200, Alain Gaillard :
Si j'écris une classe qui définit l'opérator =, l'auto-affectation je la teste systématiquement.
Ce qui complique le code, pour un résultat imperceptible dans la plupart des cas.
Compliquer le code en rajoutant des variables ou des structures "if" simplement dans l'idée que peut-être, un jour, ça accélérera le programme, c'est de l'optimisation prématurée.
On Fri, 22 Sep 2006 18:08:38 +0200, Alain Gaillard
<alain_gaillard28@hotmail.fr>:
Si j'écris une classe qui définit l'opérator =, l'auto-affectation je la
teste systématiquement.
Ce qui complique le code, pour un résultat imperceptible dans la
plupart des cas.
Compliquer le code en rajoutant des variables ou des structures "if"
simplement dans l'idée que peut-être, un jour, ça accélérera le
programme, c'est de l'optimisation prématurée.
On Fri, 22 Sep 2006 18:08:38 +0200, Alain Gaillard :
Si j'écris une classe qui définit l'opérator =, l'auto-affectation je la teste systématiquement.
Ce qui complique le code, pour un résultat imperceptible dans la plupart des cas.
Compliquer le code en rajoutant des variables ou des structures "if" simplement dans l'idée que peut-être, un jour, ça accélérera le programme, c'est de l'optimisation prématurée.
Fabien LE LEZ
On Fri, 22 Sep 2006 18:54:16 +0200, Alain Gaillard :
Bien sûr que la version de Fabien est meilleure, mais au niveau de l'élégance du code seulement.
Si j'écris une classe qui définit l'opérator =, l'auto-affectation je la teste systématiquement.
Ce qui complique le code, pour un résultat imperceptible dans la plupart des cas.
Je ne trouve pas, au contraire. Je parle de la complication.
Compliquer le code en rajoutant des variables ou des structures "if" simplement dans l'idée que peut-être, un jour, ça accélérera le programme, c'est de l'optimisation prématurée.
Mais là ce n'est pas question d'optimisation, pas du tout. Il est vrai que c'est venu dans la conversation dans un contexte d'optimsation, mais ce n'est pas ce que je voulais dire en disant que je ne partageias pas le point de vue de Herb Sutter. C'est question de simplicité selon moi. C'est tellement plus simple d'écrire
if(this == &src) return *this;
que de faire attention à ne pas libérer deux foix une même ressource qui serait détenue par la classe. Tu dis que ça complique le code, moi je dis que ça le simplifie. Comme je l'ai dit je trouve ça tellement naturel. C'est la raison première. Reste les éventuelles constructions inutiles des éventuels objets membres de la classe en cas d'auto-affectation. Eviter ces constructions est un corollaire du test et vraiment je trouve que ce n'est plus mal.
Sans doute qu'il y a des cas où l'on pourrait se dispenser du test. Disons que j'ai l'habitude de toujours faire comme ça peut être un peu par paresse aussi. Parce que je trouve justement que le coût du test est négligeable tandis qu'il me simplifie la vie.
Mais vraiment je trouve pas que le code soit compliqué. Si je lis du code écrit et que je vois
if(this == &src) return *this;
au début du code alors je suis sûr qu'il n'y a pas de problème. Sinon faut tout lire en ayant le cas particulier de l'auto-affectation en tête. Enfin ce n'est que mon avis :)
-- Alain
Si j'écris une classe qui définit l'opérator =, l'auto-affectation je la
teste systématiquement.
Ce qui complique le code, pour un résultat imperceptible dans la
plupart des cas.
Je ne trouve pas, au contraire. Je parle de la complication.
Compliquer le code en rajoutant des variables ou des structures "if"
simplement dans l'idée que peut-être, un jour, ça accélérera le
programme, c'est de l'optimisation prématurée.
Mais là ce n'est pas question d'optimisation, pas du tout. Il est vrai
que c'est venu dans la conversation dans un contexte d'optimsation, mais
ce n'est pas ce que je voulais dire en disant que je ne partageias pas
le point de vue de Herb Sutter. C'est question de simplicité selon moi.
C'est tellement plus simple d'écrire
if(this == &src) return *this;
que de faire attention à ne pas libérer deux foix une même ressource qui
serait détenue par la classe. Tu dis que ça complique le code, moi je
dis que ça le simplifie. Comme je l'ai dit je trouve ça tellement naturel.
C'est la raison première. Reste les éventuelles constructions inutiles
des éventuels objets membres de la classe en cas d'auto-affectation.
Eviter ces constructions est un corollaire du test et vraiment je trouve
que ce n'est plus mal.
Sans doute qu'il y a des cas où l'on pourrait se dispenser du test.
Disons que j'ai l'habitude de toujours faire comme ça peut être un peu
par paresse aussi. Parce que je trouve justement que le coût du test est
négligeable tandis qu'il me simplifie la vie.
Mais vraiment je trouve pas que le code soit compliqué. Si je lis du
code écrit et que je vois
if(this == &src) return *this;
au début du code alors je suis sûr qu'il n'y a pas de problème. Sinon
faut tout lire en ayant le cas particulier de l'auto-affectation en tête.
Enfin ce n'est que mon avis :)
Si j'écris une classe qui définit l'opérator =, l'auto-affectation je la teste systématiquement.
Ce qui complique le code, pour un résultat imperceptible dans la plupart des cas.
Je ne trouve pas, au contraire. Je parle de la complication.
Compliquer le code en rajoutant des variables ou des structures "if" simplement dans l'idée que peut-être, un jour, ça accélérera le programme, c'est de l'optimisation prématurée.
Mais là ce n'est pas question d'optimisation, pas du tout. Il est vrai que c'est venu dans la conversation dans un contexte d'optimsation, mais ce n'est pas ce que je voulais dire en disant que je ne partageias pas le point de vue de Herb Sutter. C'est question de simplicité selon moi. C'est tellement plus simple d'écrire
if(this == &src) return *this;
que de faire attention à ne pas libérer deux foix une même ressource qui serait détenue par la classe. Tu dis que ça complique le code, moi je dis que ça le simplifie. Comme je l'ai dit je trouve ça tellement naturel. C'est la raison première. Reste les éventuelles constructions inutiles des éventuels objets membres de la classe en cas d'auto-affectation. Eviter ces constructions est un corollaire du test et vraiment je trouve que ce n'est plus mal.
Sans doute qu'il y a des cas où l'on pourrait se dispenser du test. Disons que j'ai l'habitude de toujours faire comme ça peut être un peu par paresse aussi. Parce que je trouve justement que le coût du test est négligeable tandis qu'il me simplifie la vie.
Mais vraiment je trouve pas que le code soit compliqué. Si je lis du code écrit et que je vois
if(this == &src) return *this;
au début du code alors je suis sûr qu'il n'y a pas de problème. Sinon faut tout lire en ayant le cas particulier de l'auto-affectation en tête. Enfin ce n'est que mon avis :)
-- Alain
Alain Gaillard
On Fri, 22 Sep 2006 18:54:16 +0200, Alain Gaillard :
Bien sûr que la version de Fabien est meilleure, mais au niveau de l'élégance du code seulement.
En effet et c'est ce que j'appelle un code plus élégant, pour un end() sorti de la boucle, c'est bien que ça dont il était question au départ n'est-ce pas, de ne pas construire un itérateur n fois ?
-- Alain
On Fri, 22 Sep 2006 18:54:16 +0200, Alain Gaillard
<alain_gaillard28@hotmail.fr>:
Bien sûr que la version de Fabien est meilleure, mais au
niveau de l'élégance du code seulement.
En effet et c'est ce que j'appelle un code plus élégant, pour un end()
sorti de la boucle, c'est bien que ça dont il était question au départ
n'est-ce pas, de ne pas construire un itérateur n fois ?
En effet et c'est ce que j'appelle un code plus élégant, pour un end() sorti de la boucle, c'est bien que ça dont il était question au départ n'est-ce pas, de ne pas construire un itérateur n fois ?
-- Alain
Fabien LE LEZ
On Fri, 22 Sep 2006 19:37:41 +0200, Alain Gaillard :
C'est tellement plus simple d'écrire
if(this == &src) return *this;
que de faire attention à ne pas libérer deux foix une même ressource qui serait détenue par la classe.
Peux-tu donner un exemple (pas trop trivial) d'opérateur = qui fonctionne effectivement quand le test "if(this == &src)" est présent, et ne fonctionne plus quand il est absent ?
En prime, la ligne "if ... return *this" me fait penser que c'est pire que ce que j'imaginais.
Je voyais, au minimum, un truc du style
T& operator= (T const& src) { if (this != &src) { //Ici, le code } return *this; }
Note que le code
void T::Swap (T& autre) throw() {...}
T& operator= (T const& src) { T nouveau (src); Swap (nouveau); return *this; }
fonctionne avec ou sans le test, qui devient alors une simple optimisation.
On Fri, 22 Sep 2006 19:37:41 +0200, Alain Gaillard
<alain_gaillard28@hotmail.fr>:
C'est tellement plus simple d'écrire
if(this == &src) return *this;
que de faire attention à ne pas libérer deux foix une même ressource qui
serait détenue par la classe.
Peux-tu donner un exemple (pas trop trivial) d'opérateur = qui
fonctionne effectivement quand le test "if(this == &src)" est présent,
et ne fonctionne plus quand il est absent ?
En prime, la ligne "if ... return *this" me fait penser que c'est pire
que ce que j'imaginais.
Je voyais, au minimum, un truc du style
T& operator= (T const& src)
{
if (this != &src)
{
//Ici, le code
}
return *this;
}
Note que le code
void T::Swap (T& autre) throw()
{...}
T& operator= (T const& src)
{
T nouveau (src);
Swap (nouveau);
return *this;
}
fonctionne avec ou sans le test, qui devient alors une simple
optimisation.
On Fri, 22 Sep 2006 19:37:41 +0200, Alain Gaillard :
C'est tellement plus simple d'écrire
if(this == &src) return *this;
que de faire attention à ne pas libérer deux foix une même ressource qui serait détenue par la classe.
Peux-tu donner un exemple (pas trop trivial) d'opérateur = qui fonctionne effectivement quand le test "if(this == &src)" est présent, et ne fonctionne plus quand il est absent ?
En prime, la ligne "if ... return *this" me fait penser que c'est pire que ce que j'imaginais.
Je voyais, au minimum, un truc du style
T& operator= (T const& src) { if (this != &src) { //Ici, le code } return *this; }
Note que le code
void T::Swap (T& autre) throw() {...}
T& operator= (T const& src) { T nouveau (src); Swap (nouveau); return *this; }
fonctionne avec ou sans le test, qui devient alors une simple optimisation.
Alain Gaillard
Peux-tu donner un exemple (pas trop trivial) d'opérateur = qui fonctionne effectivement quand le test "if(this == &src)" est présent, et ne fonctionne plus quand il est absent ?
Je l'ai dit, ça fois que tu risques de libérer deux fois la même ressource.
En prime, la ligne "if ... return *this" me fait penser que c'est pire que ce que j'imaginais.
Ah bon ?
Je voyais, au minimum, un truc du style
T& operator= (T const& src) { if (this != &src) { //Ici, le code } return *this; }
Qu'il y a deux fois return *this ? Moi ça ne me gêne pas.
Note que le code
void T::Swap (T& autre) throw() {...}
T& operator= (T const& src) { T nouveau (src); Swap (nouveau); return *this; }
Moi aussi j'ai lu Sutter ;)
fonctionne avec ou sans le test, qui devient alors une simple optimisation.
Sauf que la création du temporaire, à supposer que le constructeur de copie existe (bon je pousse un peu, il y est très très probablement ;) peut te lever une exception qui dans le contexte de l'auto-affectation a quand même un côté un peu idiot. Obstiné, je préfère:
Peux-tu donner un exemple (pas trop trivial) d'opérateur = qui
fonctionne effectivement quand le test "if(this == &src)" est présent,
et ne fonctionne plus quand il est absent ?
Je l'ai dit, ça fois que tu risques de libérer deux fois la même ressource.
En prime, la ligne "if ... return *this" me fait penser que c'est pire
que ce que j'imaginais.
Ah bon ?
Je voyais, au minimum, un truc du style
T& operator= (T const& src)
{
if (this != &src)
{
//Ici, le code
}
return *this;
}
Qu'il y a deux fois return *this ? Moi ça ne me gêne pas.
Note que le code
void T::Swap (T& autre) throw()
{...}
T& operator= (T const& src)
{
T nouveau (src);
Swap (nouveau);
return *this;
}
Moi aussi j'ai lu Sutter ;)
fonctionne avec ou sans le test, qui devient alors une simple
optimisation.
Sauf que la création du temporaire, à supposer que le constructeur de
copie existe (bon je pousse un peu, il y est très très probablement ;)
peut te lever une exception qui dans le contexte de l'auto-affectation a
quand même un côté un peu idiot. Obstiné, je préfère:
Peux-tu donner un exemple (pas trop trivial) d'opérateur = qui fonctionne effectivement quand le test "if(this == &src)" est présent, et ne fonctionne plus quand il est absent ?
Je l'ai dit, ça fois que tu risques de libérer deux fois la même ressource.
En prime, la ligne "if ... return *this" me fait penser que c'est pire que ce que j'imaginais.
Ah bon ?
Je voyais, au minimum, un truc du style
T& operator= (T const& src) { if (this != &src) { //Ici, le code } return *this; }
Qu'il y a deux fois return *this ? Moi ça ne me gêne pas.
Note que le code
void T::Swap (T& autre) throw() {...}
T& operator= (T const& src) { T nouveau (src); Swap (nouveau); return *this; }
Moi aussi j'ai lu Sutter ;)
fonctionne avec ou sans le test, qui devient alors une simple optimisation.
Sauf que la création du temporaire, à supposer que le constructeur de copie existe (bon je pousse un peu, il y est très très probablement ;) peut te lever une exception qui dans le contexte de l'auto-affectation a quand même un côté un peu idiot. Obstiné, je préfère: