Newsgroup: it.comp.lang.c++
Titolo: domanda su operator = ()

domanda:
ha senso dichiarare un operatore di assegnamento con questo prototipo:
class Pippo {
....
	const Pippo &operator(const Pippo &p ); 
???
in genere il const davanti ad una referenza che viene restituita serve
ad impedire cose del tipo:
pippo.funzione_che_resituisce_una_ref() = qualcosa;
ma in questo caso mi sembra un po' una contraddizione metterlo....
o c'e' una differenza dallo scrivere lo stesso operatore senza il const?
ciao 
andrea

         const Pippo &operator = (const Pippo &p );
ehm...

 ha scritto nel messaggio
news:3A219914...@to.infn.it...

considera operator = come una funzione , quindi :
a = b ;
può essere tradotta
a.operator=(b);
inoltre questa funzione ritorna un valore 'a' che ora è uguale a 'b' .Questo
valore non deve essere modificato ovviamente , quindi per sicurezza si mette
il const.

 };
sullo Stroustrup 2 ediz, tutti gli esempio vengono riportati secondo
una dichiarazione del tipo
Pippo &operator( const Pippo &);
Dice anche che, dove possibile, il compilatore genera un operatore di
assegnamento dichiarato in questa maniera, per una classe X:
X &X::operator =( const X &);
oppure
X &X::operator =( X &);
Se tu dichiari il tuo operator = alla tua maniera, sia il GCC 2.95.2
che il Borland C++ 5.5.1 non utilizzano mai la versione che hai
dichiarato tu, ma quella che si sono forniti da soli come spiega
Stroustrup.

psycho wrote:

Ma le funzioni in C++ non si identificavano solo in unfnzione degli 
argomenti e del nome ? Perche questi compilatori fanno questa 
"discriminazione" ( la differenza e' solo nel tipo di ritorno ... )

 Questo valore non deve essere modificato ovviamente , quindi per
sicurezza si mette il const.
io normalmente utilizzo la stessa dichiarazione di Stroustrup, cioè
senza il const.

 senza il const.
Senno non sarebbe possibile codice del tipo
a=b=c;

 a=b=c;
appunto, anche se credo che per la associatività del = dovrebbe essere
( a = b) = c;
ma non ne sono sicuro, comunque è esattamente x quello che lo faccio.

ma non ne sono sicuro, comunque è esattamente x quello che lo faccio.
Esattamente il contrario... con il raggruppamento che hai scritto
b non cambierebbe valore. L'operatore di assegnazione raggruppa
a destra e non a sinistra.
Il fatto di tornare un const reference oppure non non ha nulla a
che vedere con le assegnazioni in cascata. Alcuni autori dicevano
che visto che con gli interi e' ammesso fare
   (a=b)=c;
allora dovrebbe esserlo anche con delle classi definite dall'utente
se non ci sono ragioni specifiche per impedirlo ("in doubt do what
int does" come dice Scott Meyers).
Qualcuno ha pero' fatto notare che con gli interi l'istruzione
appena esposta e' undefined behaviour (assegna due volte ad a senza
un sequence point fra le due assegnazioni).
Io resto comunque dell'idea che e' giusto tornare un non-const
reference... ma e' un punto dibattuto.
HTH
Andrea
--
Andrea Griffini, Programmer
http://www.netservers.com/~agriff

a=b=c;
No... l'operatore '=' raggruppa da destra a sinistra proprio
per poter effettuare le assegnazioni in cascata:
  a=b=c
significa
  a=(b=c)
e quindi il risultato dell'assegnazione a b viene usato a
*destra* dell'operatore di assegnazione ad a.
Io comunque preferisco tornare un reference non-const perche'
non vedo nulla di male (non lo ritengo cioe' un "errore" di
logica) nell'assegnare ancora al risultato di una assegnazione
(anche se la cosa non mi sembra possa servire ad un granche').


 ma non ne sono sicuro, comunque è esattamente x quello che lo faccio.
Infatti non è così. L'associatività è esattamente al contrario.
EMG

 per poter effettuare le assegnazioni in cascata:
Mi riferivo alla possibilita' dell'assegnazione in cascata ( che ha senso 
"logico" solo se da destra a sinistra , ovviamente )

   (a=b)=c;
Spiegatemi una cosa :
Che cosa cambia nel trattamento di questa espressione tra C e C++ ?
Infatti in C questa espressione non e' legale, visto che (a=b) viene
calcolato come rvalue. In C++, invece, sembra essere semanticamente
corretta.
--
Andrea Laforgia (ICQ 87230455)
------------------------------ 
#exclude <windows.h>

 ( a = b) = c;
scusate, effettivamente ho toppato alla grande
però con
a = b = c;
non farebbe alcuna differenza dichiarare
const X &operator =( const X &);
anzichè
X &operator =( const X &);
o sbaglio (ancora)?

corretta.
Sintatticamente corretta. In C++ comunque e' undefined behaviour
(con i tipi nativi) per la ragione che non e' ammesso che una
variabile subisca piu' di un effetto collaterale prima che
intervenga un sequence point. Due assegnazioni ad a non sono
quindi permesse in questo caso.
Sul perche' l'operatore di assegnazione torni un reference invece
di un valore non sono sicuro... forse e' stato fatto per non dover
pagare il costo di una copia inutile ad ogni assegnazione senza
per questo rinunciare alle assegnazioni in cascata.
Si sarebbe pero' potuto tornare un const reference ... ma alcune
classi richiedono che l'istanza venga modificata anche quando e'
*sorgente* di una assegnazione (es. reference counting o auto_ptr).
Boh... :D
Ho letto da qualche parte che una volta Andrew Koneig ha spiegato
i retroscena di questa scelta che puo' apparire a prima vista
bizzarra... ma non ho letto questa spiegazione e non ne trovo
piu' i riferimenti :(((


 "logico" solo se da destra a sinistra , ovviamente )
... e cosi' si puo' ritornare un const & ....
Scusate mi sono accorto ora della sottigliezza !
 

risposta