OVH Cloud OVH Cloud

operateur =

33 réponses
Avatar
mohamed92000
Bonjour a tous,
ça fait 5 jours que j'ai posté ce message et je ne le vois pas sur le
forum problement un problème!
J'ai trouvé le code suivant pour l'orérateur =:
const Maclass& Maclass::operator=(const Maclass&right)
{
if (&right!=this)
{
this->Maclass::~CCSOUtilSurfaceECGBuffer();
::new(this) Maclass(right);

}
return *this;
}
question :
::new(this) Maclass(right); : je ne comprends pas le sens de cette
ligne et si c'est bien de faire comme sa?
moi j'aurai suggéré de faire une fonction commune qui sera appelée par
le constructeur de copie et l'opérateur = "pour la lisibilité"

10 réponses

1 2 3 4
Avatar
Jean-Marc Bourguet
(mourad) writes:

J'ai trouvé le code suivant pour l'orérateur =:
const Maclass& Maclass::operator=(const Maclass&right)
{
if (&right!=this)
{
this->Maclass::~CCSOUtilSurfaceECGBuffer();
Ne serait-ce pas plutot

this->~Maclass();
? Je ne vois pas ce que vient faire CCSOUtilSurfaceECGBuffer ici.

::new(this) Maclass(right);

}
return *this;
}
question :
::new(this) Maclass(right);

: je ne comprends pas le sens de cette ligne


Ca appelle le constructeur de copie de Maclass avec l'argument right
sur this.

et si c'est bien de faire comme sa?


C'est une fausse bonne idee qui a des problemes voir dans les
archives.

moi j'aurai suggéré de faire une fonction commune qui sera appelée
par le constructeur de copie et l'opérateur = "pour la lisibilité"


Ce qui a l'inconveniant de construire d'abord par defaut puis de
copier. Mais si c'est applicable, cette fonction commune peut-etre
l'operateur= lui-meme:

MaClasse::MaClasse(MaClasse const& autre) {
*this = autre;
}

A+

--
Jean-Marc
FAQ de fclc++: http://www.cmla.ens-cachan.fr/~dosreis/C++/FAQ
C++ FAQ Lite en VF: http://www.ifrance.com/jlecomte/c++/c++-faq-lite/index.html
Site de usenet-fr: http://www.usenet-fr.news.eu.org

Avatar
Benoit Dejean
Le Mon, 27 Oct 2003 04:22:06 -0800, mourad a écrit :

Bonjour a tous,
ça fait 5 jours que j'ai posté ce message et je ne le vois pas sur le
forum problement un problème!
J'ai trouvé le code suivant pour l'orérateur =: const Maclass&
Maclass::operator=(const Maclass&right) {
if (&right!=this)
{
this->Maclass::~CCSOUtilSurfaceECGBuffer(); ::new(this)
Maclass(right);

}
return *this;
}


est que la zone mémoire de this t'appartient ? si c'est quelque chose en
pile, ça va saigner ?

c'est pas très beau tout ça. pour quoi ne pas faire une fonction clear()
(également appelé dans le destructeur) ? d'autre par, tu peux aussi
faire une fonction assign que tu appelles également dans ton constructeur
par recopie. en tous cas ta version n'est pas très performante (ou
désalloue pour réallouer)

personnellement, moi je définirais une fonction membre swap et operator se résume à un simple swap avec une copie

Avatar
Laurent DELEPINE
mourad wrote:

::new(this) Maclass(right); : je ne comprends pas le sens de cette
ligne et si c'est bien de faire comme sa?


Cette version de new est l'operateur de placement. Il appelle le
constructeur mais au lieu de reserver elle meme la memoire, il utilise
le pointeur transmis en parametre comme adresse de l'objet

moi j'aurai suggéré de faire une fonction commune qui sera appelée par
le constructeur de copie et l'opérateur = "pour la lisibilité"


Ce n'est pas toujours possible. Les constructeurs peuvent initialiser
les references, pas les fonctions normales.


Jusqu'a il y a pas longtemps, c'est l'idiome recommandé. Aujourd'hui on
prefere utiliser un fonction swap.


A+

LD

Avatar
kanze
Laurent DELEPINE wrote in message
news:<3f9d0fe8$0$246$...
mourad wrote:

::new(this) Maclass(right); : je ne comprends pas le sens de cette
ligne et si c'est bien de faire comme sa?


Cette version de new est l'operateur de placement. Il appelle le
constructeur mais au lieu de reserver elle meme la memoire, il utilise
le pointeur transmis en parametre comme adresse de l'objet

moi j'aurai suggéré de faire une fonction commune qui sera appelée
par le constructeur de copie et l'opérateur = "pour la lisibilité"


Ce n'est pas toujours possible. Les constructeurs peuvent initialiser
les references, pas les fonctions normales.

Jusqu'a il y a pas longtemps, c'est l'idiome recommandé. Aujourd'hui
on prefere utiliser un fonction swap.


Je ne sais pas dans quelle mésure il était « recommandé ». Certains
disaient qu'il pouvait servir à resoudre certains problèmes, mais
d'autres l'ont opposé depuis le debut.

--
James Kanze GABI Software mailto:
Conseils en informatique orientée objet/ http://www.gabi-soft.fr
Beratung in objektorientierter Datenverarbeitung
11 rue de Rambouillet, 78460 Chevreuse, France, +33 (0)1 30 23 45 16


Avatar
kanze
Benoit Dejean wrote in message
news:...

personnellement, moi je définirais une fonction membre swap et
operator= se résume à un simple swap avec une copie


Tu es le deuxième à préconciser une fonction swap sans expliquer ce que
tu entends par ça. Écrire quelque chose du genre :

MaClasse&
MaClasse::operator=( MaClasse const& other )
{
MaClasse tmp( other ) ;
std::swap( *this, tmp ) ;
return *this ;
}

n'est pas une bonne solution. L'idiome de swap ne marche que si tu t'es
déjà arrangé pour que swap ne lève pas d'exceptions (et typiquement,
pour qu'il soit plus efficace que l'algorithme par défaut).

En général, swap est préconcisé dans le cas où la classe contient des
pointeurs à la mémoire dynamique -- on peut alors swapper les pointeurs
de façon très efficace, et sans risque de lever une exception. En
revanche, si la classe ne contient que des types de base (int, double,
etc.), dont l'affectation ne peut pas échouer, il n'a aucune raison de
faire autrement que l'évident : affecter un membre après l'autre. Et si
la classe contient de gros objets définis par l'utilisateur qui ne
supporte pas l'idiome de swap, l'idiome de swap ne marche pas. (Mais
dans ce cas-là, j'utilise prèsque toujours l'idiome du pare-feu de
compilation, ce qui fait que la classe même ne contient qu'un seul
pointeur, et l'idiome de swap marche.)

--
James Kanze GABI Software mailto:
Conseils en informatique orientée objet/ http://www.gabi-soft.fr
Beratung in objektorientierter Datenverarbeitung
11 rue de Rambouillet, 78460 Chevreuse, France, +33 (0)1 30 23 45 16

Avatar
Benoit Dejean
Le Tue, 28 Oct 2003 00:29:15 -0800, kanze a écrit :

Benoit Dejean wrote in message
news:...

personnellement, moi je définirais une fonction membre swap et
operator= se résume à un simple swap avec une copie


Tu es le deuxième à préconciser une fonction swap sans expliquer ce
que tu entends par ça. Écrire quelque chose du genre :



n'est pas une bonne solution. L'idiome de swap ne marche que si tu t'es
déjà arrangé pour que swap ne lève pas d'exceptions (et typiquement,
pour qu'il soit plus efficace que l'algorithme par défaut).


je suis d'accord

En général, swap est préconcisé dans le cas où la classe contient
des pointeurs à la mémoire dynamique -- on peut alors swapper les
pointeurs de façon très efficace, et sans risque de lever une
exception.


s'il a la flemme de réécrire le code de son destructeur et de son
constructeur de copie modulo quelque modifications, on peut
raisonnablement penser que c'est parce que c'est truffer de new/delete

En
revanche, si la classe ne contient que des types de base (int, double,
etc.), dont l'affectation ne peut pas échouer, il n'a aucune raison de
faire autrement que l'évident : affecter un membre après l'autre.


Il semble de pas s'en satisfaire

Et si
la classe contient de gros objets définis par l'utilisateur qui ne
supporte pas l'idiome de swap, l'idiome de swap ne marche pas. (Mais
dans ce cas-là, j'utilise prèsque toujours l'idiome du pare-feu de
compilation, ce qui fait que la classe même ne contient qu'un seul
pointeur, et l'idiome de swap marche.)


j'aillais le dire, je fais pareil, mais j'aurais dit Cheshire Cat. Merci
pour tes précisions












:oD


Avatar
mohamed92000
Benoit Dejean wrote in message news:...
Le Mon, 27 Oct 2003 04:22:06 -0800, mourad a écrit :

est que la zone mémoire de this t'appartient ? si c'est quelque chose en
pile, ça va saigner ?

c'est pas très beau tout ça. pour quoi ne pas faire une fonction clear()
(également appelé dans le destructeur) ? d'autre par, tu peux aussi
faire une fonction assign que tu appelles également dans ton constructeur
par recopie. en tous cas ta version n'est pas très performante (ou
désalloue pour réallouer)

personnellement, moi je définirais une fonction membre swap et operator > se résume à un simple swap avec une copie.


est ce que tu peux s.t.p donner un exemple avec un petit code simple?
c'est quoi une fonction swape et une fonction assign."juste une petite
indication dans l'ésprit du sujet je sais qu'il ya de la doc sur sa"
merci à tous.

Avatar
Christophe Lephay
Laurent DELEPINE wrote:
wrote:
(Mais
dans ce cas-là, j'utilise prèsque toujours l'idiome du pare-feu de
compilation, ce qui fait que la classe même ne contient qu'un seul
pointeur, et l'idiome de swap marche.)


En quoi consiste cet idiome du pare-feu de compilation


class imp
{
public:
void fonction();
};

class proxy
{
imp * pimp;
public:
void fonction() { pimp->fonction(); }
};

Les intérets :
* pimp peut varier de manière dynamique (pour peu que fonction soit
virtuelle, notemment)
* en cas de modification de la classe imp, seule celle-ci doit être
recompilée
* l'implémentation n'est pas seulement encapsulée (comme ce serait le cas
avec juste des données private), elle est masquée dans la classe imp (il
suffit d'en fournir le fichier objet). C'est ce point, je pense, qui
justifie l'appelation "compiler firewall", peut-être aussi le point
précédent.

Je crois que "compiler firewall" est synonyme de classe proxy, de pimple ou
pimp ("pointeur sur implémentation") et de cheschire cat...

Chris


Avatar
Christophe Lephay
mourad wrote:
Benoit Dejean wrote in message
news:...

est que la zone mémoire de this t'appartient ? si c'est quelque
chose en pile, ça va saigner ?

c'est pas très beau tout ça. pour quoi ne pas faire une fonction
clear() (également appelé dans le destructeur) ? d'autre par, tu
peux aussi faire une fonction assign que tu appelles également dans
ton constructeur par recopie. en tous cas ta version n'est pas très
performante (ou désalloue pour réallouer)

personnellement, moi je définirais une fonction membre swap et
operator= se résume à un simple swap avec une copie.


est ce que tu peux s.t.p donner un exemple avec un petit code simple?
c'est quoi une fonction swape et une fonction assign."juste une petite
indication dans l'ésprit du sujet je sais qu'il ya de la doc sur sa"


Concernant swap, voir les posts de James et Laurent. Pour assign, rien de
plus simple :

class truc
{
int a, b, c;

void assign( const truc& un_truc ) {
a=un_truc.a; b=un_truc.b; c=un_truc.c; }

public:
truc( int aa=0, int bb=0, int cc=0 ) : a( aa ), b( bb ), c( cc ) {}
truc( const truc& un_truc ) { assign( un_truc ); }
truc& operator=( const truc& un_truc ) { assign( un_truc ); }
};

L'idée est que l'affectation a lieu dans assign, ce qui permet de factoriser
le code du constructeur copie et de l'opérateur d'affectation, pour peu que
celà en vaille la peine (ce qui n'est pas évident avec l'exemple
ci-dessus)...

Chris


Avatar
Jean-Marc Bourguet
"Christophe Lephay" writes:

Laurent DELEPINE wrote:

En quoi consiste cet idiome du pare-feu de compilation


class imp
{
public:
void fonction();
};

class proxy
{
imp * pimp;
public:
void fonction() { pimp->fonction(); }
};

Les intérets :
* pimp peut varier de manière dynamique (pour peu que fonction soit
virtuelle, notemment)
* en cas de modification de la classe imp, seule celle-ci doit être
recompilée
* l'implémentation n'est pas seulement encapsulée (comme ce serait le cas
avec juste des données private), elle est masquée dans la classe imp (il
suffit d'en fournir le fichier objet). C'est ce point, je pense, qui
justifie l'appelation "compiler firewall", peut-être aussi le point
précédent.

Je crois que "compiler firewall" est synonyme de classe proxy, de pimple ou
pimp ("pointeur sur implémentation") et de cheschire cat...


Pas tout a fait. proxy c'est un DP, ou un objet agit a la place d'un
autre. Le pare-feu de compilation est plus un idiome qui utilise un
proxy pour eviter la recompilation quand l'implementation change.

Donc, mettre proxy::fonction en inline ci-dessus fait que ce n'est pas
du tout un bon exemple.

A+
--
Jean-Marc
FAQ de fclc++: http://www.cmla.ens-cachan.fr/~dosreis/C++/FAQ
C++ FAQ Lite en VF: http://www.ifrance.com/jlecomte/c++/c++-faq-lite/index.html
Site de usenet-fr: http://www.usenet-fr.news.eu.org


1 2 3 4