Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

[débutant] constructeur de copie vs. opérateur d'affectation.

16 réponses
Avatar
cyrcocq
Bonjour,
Soit un objet A de la classe MaClasse
Si on fait
MaClasse B=A

C'est l'opérateur de copie ou d'afectation qui est utilisé?
Ca dépend des cas?

10 réponses

1 2
Avatar
Fabien LE LEZ
On Fri, 30 Sep 2005 23:25:30 +0200, "cyrcocq" :

Si tu écris

MaClasse machin ...

c'est forcément un constructeur qui est appelé.

L'opérateur d'affectation n'est appelé que si tu assignes une nouvelle
valeur à un objet existant :

MaClasse machin= truc; // constructeur
machin= bidule; // operator


Si on fait
MaClasse B=A


Supposons que A soit de classe "MaClasse".
Alors, les deux lignes ci-dessous sont exactement équivalentes :

MaClasse B= A;
MaClasse B (A);

Si maintenant A est de classe "MonAutreClasse", et que MaClasse a un
constructeur prenant un MonAutreClasse comme seul argument :

class MaClasse
{
public: MaClasse (MonAutreClasse const&);
...
};

Alors, ben... j'ai un doute ;-)

Il me semble que la ligne

MaClasse B= A;

est équivalente à

MaClasse B (MaClasse (A));

(i.e. un objet temporaire est créé.)


Mais en pratique, c'est à peu près la même chose que

MaClasse B (A);

Avatar
Fabien LE LEZ
On Fri, 30 Sep 2005 23:46:41 +0200, Fabien LE LEZ
:

Alors, ben... j'ai un doute ;-)


Doute levé par l'item 42 de "Exceptional C++" : c'est bien ce que
j'avais écrit.
La vache, j'ai apparemment réussi à écrire un post sans la moindre
connerie -- demain il va pleuvoir !..

Notre ami Herb conseille d'ailleurs de ne jamais écrire

MaClasse x= y;

mais systématiquement

MaClasse x (y);

Avatar
Patrick 'Zener' Brunet
Bonjour.

Je réponds à Fabien LE LEZ
On Fri, 30 Sep 2005 23:46:41 +0200, Fabien LE LEZ
:

Alors, ben... j'ai un doute ;-)


Doute levé par l'item 42 de "Exceptional C++" : c'est bien ce que
j'avais écrit.
La vache, j'ai apparemment réussi à écrire un post sans la moindre
connerie -- demain il va pleuvoir !..

Notre ami Herb conseille d'ailleurs de ne jamais écrire

MaClasse x= y;

mais systématiquement

MaClasse x (y);


Le cas terrible qui explique tout, c'est l'implémentation traditionnelle de
l'opérateur + ami, quel que soit sa sémantique finale (addition,
concaténation, etc.):

/* friend */
CTruc CTruc::operator + ( CTruc const & L, CTruc const & R)
{
CTruc result( L);

result += R;
return( result);
// Là une copie fantôme transite sur la pile
// après destruction de result
}

CTruc A, B, C;

A = B + C; // A suivre au debugger

Faites ça avec des chaînes (c'est si cool à écrire) et vous allez voir le
moulinage de copies et allocations/restitutions de buffers.

Cordialement,

--
/***************************************
* Patrick BRUNET
* E-mail: lien sur http://zener131.free.fr/ContactMe
***************************************/


Avatar
Fabien LE LEZ
On Sat, 1 Oct 2005 08:45:52 +0200, "Patrick 'Zener' Brunet"
:

Faites ça avec des chaînes (c'est si cool à écrire) et vous allez voir le
moulinage de copies et allocations/restitutions de buffers.


Tant que ça marche et que l'application finale n'en est pas
significativement ralentie, ça ne pose pas de problèmes, c'est de la
cuisine interne.

Avatar
James Kanze
Fabien LE LEZ wrote:
On Fri, 30 Sep 2005 23:46:41 +0200, Fabien LE LEZ
:


Alors, ben... j'ai un doute ;-)



Doute levé par l'item 42 de "Exceptional C++" : c'est bien ce
que j'avais écrit.
La vache, j'ai apparemment réussi à écrire un post sans la
moindre connerie -- demain il va pleuvoir !..


Notre ami Herb conseille d'ailleurs de ne jamais écrire


MaClasse x= y;


mais systématiquement


MaClasse x (y);


surtout dans le cas où la valeur d'initialisation est une
expression du genre A(b) (ou A est le nom d'une classe), n'est
pas ? C-à-d :

MaClasse x( A( b ) ) ;

:-)

(Ou avec des versions plus anciennes de Sun CC ou de VC++ -- qui
suite à des erreurs n'acceptaient pas toujours l'écriture sans
le '='.)

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


Avatar
James Kanze
Fabien LE LEZ wrote:
On Sat, 1 Oct 2005 08:45:52 +0200, "Patrick 'Zener' Brunet"
:


Faites ça avec des chaînes (c'est si cool à écrire) et vous
allez voir le moulinage de copies et allocations/restitutions
de buffers.



Tant que ça marche et que l'application finale n'en est pas
significativement ralentie, ça ne pose pas de problèmes, c'est de la
cuisine interne.


Tant que l'expression a besoin des valeurs intermédiaires, ce
n'est vraiment pas un problème que le compilateur en produit.

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


Avatar
Fabien LE LEZ
On Sat, 01 Oct 2005 19:30:47 +0200, James Kanze :

MaClasse x( A( b ) ) ;

:-)


T'es taquin ;-p

Effectivement, je l'avais oublié, ce coup-là.

Comme quoi, quand on cite des conseils, faut toujours donner l'auteur
;-)

Avatar
James Kanze
Fabien LE LEZ wrote:
On Sat, 01 Oct 2005 19:30:47 +0200, James Kanze :


MaClasse x( A( b ) ) ;



:-)



T'es taquin ;-p


N'est-ce pas ? Surtout que chaque fois que quelqu'un propose la
solution avec '=' pour éviter ce problème, je soulève l'histoire
du constructeur de copie privé.

Au fond, au moins en ce qui concerne les types de classe, je
préfère aussi la forme sans '='. Quitte à insérer des
parenthèses supplémentaires quand il faut :

MaClasse x( (A( b )) ) ;

Mais j'aime bien taquiner.

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


Avatar
Fabien LE LEZ
On Sun, 02 Oct 2005 18:59:56 +0200, James Kanze :

T'es taquin ;-p


N'est-ce pas ? Surtout que chaque fois que quelqu'un propose la
solution avec '=' pour éviter ce problème, je soulève l'histoire
du constructeur de copie privé.


Je reviens sur ce que j'ai dit : tu n'es pas taquin, tu es sadique ;-)


Avatar
Patrick 'Zener' Brunet
Bonjour.

Je réponds à Fabien LE LEZ
On Sat, 1 Oct 2005 08:45:52 +0200, "Patrick 'Zener' Brunet"
:

Faites ça avec des chaînes (c'est si cool à écrire) et vous allez
voir le moulinage de copies et allocations/restitutions de buffers.


Tant que ça marche et que l'application finale n'en est pas
significativement ralentie, ça ne pose pas de problèmes, c'est de la
cuisine interne.


Certes, mais il y a une perte de performance dont il vaut mieux être au
courant si on utilise de telles solutions pour écrire un compilateur par
exemple. Sans compter le risque d'émiettement de la mémoire dans certains
types d'applications contraintes (autres que l'applette sur une grosse
station de travail).

Quelquefois il ne suffit pas que "ça marche" ;-)

Dans un système de classes que j'ai écrit, je me suis "amusé", pour les
besoins du scénario typique de mon exemple, à implémenter un "don de buffer"
(ie: sans copie ni réallocation).
Evidemment c'est assez pointu et donc il faut savoir exactement où et quand
l'utiliser (c'est fait en interne), mais au debugger la baisse de
"moulinage" est flagrante.

Cordialement,

--
/***************************************
* Patrick BRUNET
* E-mail: lien sur http://zener131.free.fr/ContactMe
***************************************/


1 2