Questo snippet di codice:
int& func1()
{
int i;
i = 1;
return i;
}
non funzionerà perché stai restituendo un alias (un riferimento) a un oggetto con una durata limitata all'ambito della chiamata di funzione. Ciò significa che una volta func1()
ritorna, int i
muore, rendendo inutile il riferimento restituito dalla funzione perché ora si riferisce a un oggetto che non esiste.
int main()
{
int& p = func1();
/* p is garbage */
}
La seconda versione funziona perché la variabile è allocata nell'archivio gratuito, che non è vincolato alla durata della chiamata di funzione. Tuttavia, sei responsabile per delete
l'assegnazione int
.
int* func2()
{
int* p;
p = new int;
*p = 1;
return p;
}
int main()
{
int* p = func2();
/* pointee still exists */
delete p; // get rid of it
}
Tipicamente inseriresti il puntatore in qualche classe RAII e / o una funzione di fabbrica in modo da non doverlo fare da delete
solo.
In entrambi i casi, puoi semplicemente restituire il valore stesso (anche se mi rendo conto che l'esempio che hai fornito è stato probabilmente inventato):
int func3()
{
return 1;
}
int main()
{
int v = func3();
// do whatever you want with the returned value
}
Si noti che è perfettamente corretto func3()
restituire oggetti di grandi dimensioni nello stesso modo in cui restituisce valori primitivi perché quasi tutti i compilatori oggigiorno implementano una qualche forma di ottimizzazione del valore di ritorno :
class big_object
{
public:
big_object(/* constructor arguments */);
~big_object();
big_object(const big_object& rhs);
big_object& operator=(const big_object& rhs);
/* public methods */
private:
/* data members */
};
big_object func4()
{
return big_object(/* constructor arguments */);
}
int main()
{
// no copy is actually made, if your compiler supports RVO
big_object o = func4();
}
È interessante notare che l'associazione di una temporanea a un riferimento const è perfettamente legale C ++ .
int main()
{
// This works! The returned temporary will last as long as the reference exists
const big_object& o = func4();
// This does *not* work! It's not legal C++ because reference is not const.
// big_object& o = func4();
}
int& i = * new int;