Newsgroup: it.comp.lang.c++
Titolo: Tipo di ritorno const e riferimenti

Salve,
avrei 2 domande da porvi:
1) A che serve restituire come tipo di ritorno un tipo const T ?
In quali casi e' necessario? Tutto cio' che richiede un const T accetta
anche un T...
2) Quando bisogna restituire un T& ?
In generale so che e' sconsigliato restituire riferimenti a temporanei ma ho
letto che in alcuni casi e' utile in modo da concatenare le chiamate dei
metodi di un oggetto, cioe':
struct X {
 X f() { std::cout << "f" << std::endl; return *this;}
 X g() { std::cout << "g" << std::endl; return *this;}
 X h() { std::cout << "h" << std::endl; return *this;}
};
int main() {
 X x;
 x.f().g().h();
 return 0;
}
Questo codice funziona ma restituisco un X e non un X&... a che pro quindi
restituire riferimenti a oggetti?
Grazie

 restituire riferimenti a oggetti?
Forse per motivi di efficienza (per non fare la copia dell'oggetto
restituito)?
EMG
--
EMAG Software Homepage:     
http://www.emagsoftware.it
The EMG's ZX-Spectrum Page: 
http://www.emagsoftware.it/spectrum
The Best of Spectrum Games: 
http://www.emagsoftware.it/tbosg

 restituito)?
Si, ma a questo punto secondo te (voglio semplicemente il tuo parere :) e'
meglio rischiare di referenziare un temporaneo al fine di aumentare le
prestazioni?
Probabilemente va valutato caso per caso... forse conviene quando passare un
riferimento aumenta notevolmente l'efficienza e si ha (non so in che modo)
la certezza che il temporaneo verra' referenziato e usato in tempo utile
prima che esso venga distrutto.
Ciao

 restituire riferimenti a oggetti?
In questo esempio, ogni chiamata avviene su una copia diversa di 'x'. Se 
restituissi un 'T&', le varie chiamate andrebbero allo stesso oggetto.
Max

 prima che esso venga distrutto.
Mai passare un riferimento ad una variabile al di fuori del suo campo di
esistenza. Il programma C++ non ha la possibilità di controllare quando la
memoria sarà rilasciata e occupata da altri dati (solo in Assembly puoi
gestire lo stack in modo diretto). hai solo la certezza di fare un pessimo
programma che combinerà dei guai prima o poi (meglio che 'crashi' subito
così te ne accorgi in tempo).
Saluti,
fabiomdf
--------------------------------
Inviato via 
http://arianna.libero.it/usenet/

 func() = X;
Ciao,
Credo che non si possa scrivere "func() = X;" perchè il valore restituito
non è un 'lvalue' anche se si dichiara "T func() { return T(); }" (cioè
senza il const).
[SKIP]


 senza il const).
Il valore restituito e' un'oggetto, anche se non essendo assegnato a niente
viene perso. In ogni caso l'istruzione (considerando che X sia di tipo T):
func() = X;
se func restituisce un non const e' lecita, infatti l'oggetto e' un l-value.
Se invece restituisce un const l'istruzione segnala errore. Pero' mi chiedo:
se func() e' const non dovrebbe essere lecito il primo assegnamento? Un po
come se fosse un oggetto const come :
const T y = X; ??
Oppure si ha errore perche nel momento che viene chiamata func() il
temporaneo e' gia stato creato e quindi inizializzato dal sistema e
l'istruzione:
func() = X;
viene considerata come un secondo assegnamento ad un oggetto const?
Grazie

Questo e' vero se T e' un tipo nativo. Se invece e' un tipo definito
dall'utente l'operatore di assegnamento e' una funzione membro come
tutte le altre e puo' essere chiamata su qualsiasi oggetto non const.
Ciao,
Nicola

 
Questo non è un assegnamento, è un'inizializzazione. In questo caso, 
operator= non viene invocato.
Ad ogni modo, ho fatto l'esempio dell'assegnamento come caso particolare di 
funzione membro non const. Come ha precisato Nicola, se T è un tipo 
built-in, l'assegnamento non è possibile comunque (const o non const).
Max

 senza il const).
Se fosse vero, non si potrebbe fare vector<int> v(1); v[0] = 1;
visto che v[0] significa chiamare vector::operator[] . E l'uguale da
dove verrebbe? Si può fare proprio perchè operator[] torna un reference.
-- 
int

 se func restituisce un non const e' lecita, infatti l'oggetto e' un l-value.
Questa è la principale ragione per cui operator++(int) ritorna un const,
afaik.
-- 
[ RiK0                                ]
[ Go away! The internet is full!      ]
[ Non credo negli schemi non vincenti ]

 operator= non viene invocato.
Quindi ho ragione a dire che l'inizializzazione avviene nel momento in cui
viene creato in temporaneo?

 viene creato in temporaneo?
Per definizione, l'inizializzazione avviene quando l'oggetto è creato. 
Max

 int
Leggi bene: dove sta il reference in "T func() { return T(); }"?
Ciao,


 fabiomdf
E comunque Nicola Musatti ha giustamente precisato che quanto ho scritto
vale per i valori di tipo built-in. Leggi suo post stesso thread.


 fabiomdf
Mi riferivo a func() = X in genere. Un reference tornato da una funzione
o membro di una classe puo' essere assegnabile e puo' anche non essere
built-in (o POD, plain old data, che differenza c'è ?).
-- 
int