Cet extrait de code :
int& func1()
{
int i;
i = 1;
return i;
}
ne fonctionnera pas car vous renvoyez un alias (une référence) à un objet dont la durée de vie est limitée à la portée de l'appel de fonction. Cela signifie qu'une fois que func1()
retours, int i
meurt, ce qui rend la référence renvoyée par la fonction sans valeur car elle se réfère maintenant à un objet qui n'existe pas.
int main()
{
int& p = func1();
/* p is garbage */
}
La deuxième version fonctionne car la variable est allouée sur le free store, qui n'est pas lié à la durée de vie de l'appel de fonction. Cependant, vous êtes responsable de delete
de l'allocation 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
}
En règle générale, vous devez envelopper le pointeur dans un fichier RAII et/ou une fonction d'usine afin que vous n'ayez pas à delete
vous-même.
Dans les deux cas, vous pouvez simplement retourner la valeur elle-même (bien que je réalise que l'exemple que vous avez fourni était probablement artificiel) :
int func3()
{
return 1;
}
int main()
{
int v = func3();
// do whatever you want with the returned value
}
Notez qu'il est parfaitement possible de renvoyer des objets de grande taille de la même manière. func3()
renvoie des valeurs primitives parce qu'à peu près tous les compilateurs implémentent aujourd'hui une certaine forme de optimisation de la valeur de retour :
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();
}
Il est intéressant de noter que la liaison d'un temporaire à un const la référence est C++ parfaitement légal .
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();
}
1 votes
Si vous changez func1() pour utiliser la mémoire allouée dynamiquement, alors ils sont identiques :-)
int& i = * new int;
1 votes
Relié à des locaux constants : stackoverflow.com/questions/2784262/