Este fragmento de código:
int& func1()
{
int i;
i = 1;
return i;
}
no funcionará porque usted está volviendo un alias (una referencia) a un objeto con un tiempo de vida limitado al ámbito de la llamada de función. Eso significa que una vez que func1()
regresa, int i
muere, haciendo que la referencia devuelta por la función no tenga valor porque ahora se refiere a un objeto que no existe.
int main()
{
int& p = func1();
/* p is garbage */
}
La segunda versión funciona porque la variable se asigna en la tienda libre, que no está ligada a la vida útil de la llamada a la función. Sin embargo, usted es responsable de delete
ing el int
asignado.
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
}
Normalmente le envuelva el puntero en alguna RAII clase y/o una función de fábrica, por lo que no tiene que delete
usted mismo.
En cualquiera de los casos, sólo puede devolver el valor en sí (aunque reconozco el ejemplo que nos ha facilitado probablemente fue inventado):
int func3()
{
return 1;
}
int main()
{
int v = func3();
// do whatever you want with the returned value
}
Tenga en cuenta que está perfectamente bien para volver grandes objetos de la misma manera func3()
vuelve primitiva los valores, porque casi todos hoy en día compilador implementa algún tipo de return value optimization:
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();
}
Curiosamente, la unión de un temporal a un const ref erence es perfectly legal 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();
}
No es correcto. –
Si cambia func1() para usar memoria asignada dinámicamente, entonces son lo mismo :-) 'int & i = * new int;' –
@Martin ¿Quién lo eliminará? – balki