c++ - tipos - Devolver la referencia constante a la variable local de una función
variables locales ejemplos (4)
1. ¿Es correcta la implementación
getA1()
? Siento que es incorrecta, ya que es la dirección de devolución de la variable local o temporal.
La única versión de getAx()
que es correcta en su programa es getA3()
. Los otros tienen un comportamiento indefinido sin importar cómo los use más adelante.
2. ¿Cuál de las declaraciones en la parte principal (1,2,3) conducirá a un comportamiento indefinido?
En un sentido ninguno de ellos. Para 1 y 2, el comportamiento indefinido es como resultado de los cuerpos de las funciones. Para la última línea, newA3
debería ser un error de compilación ya que no puede vincular una referencia temporal a una referencia no const.
3. En
const A& newA1 = getA1();
¿las garantías estándar que el límite temporal por una referenciaconst
no se destruirá hasta que la referencia salga del alcance?
No. El siguiente es un ejemplo de eso:
A const & newConstA3 = getA3 ();
Aquí, getA3()
devuelve un temporal y la duración de ese temporal ahora está vinculada al objeto newConstA3
. En otras palabras, el temporal existirá hasta que newConstA3
fuera del alcance.
Tengo algunas preguntas sobre cómo devolver una referencia a una variable local desde una función:
class A
{
public:
A(int xx):x(xx)
{
printf("A::A()/n");
}
};
const A& getA1()
{
A a(5);
return a;
}
A& getA2()
{
A a(5);
return a;
}
A getA3()
{
A a(5);
return a;
}
int main()
{
const A& newA1 = getA1(); //1
A& newA2 = getA2(); //2
A& newA3 = getA3(); //3
}
Mis preguntas son =>
¿Es correcta la implementación de
getA1()
? Siento que es incorrecto ya que devuelve la dirección de una variable local o temporal.¿Cuál de las afirmaciones en
main
(1,2,3) conducirá a un comportamiento indefinido?En
const A& newA1 = getA1();
¿El estándar garantiza que un límite temporal por una referencia constante no será destruido hasta que la referencia salga del alcance?
Creo que el problema principal es que no regresas temporalmente, deberías
return A(5);
más bien que
A a(5);
return a;
De lo contrario, devolverá una dirección de variable local, no temporal. Y la referencia temporal a const solo funciona para temporarios.
Creo que se explica aquí: herbsutter.wordpress.com/2008/01/01/…
Q1: Sí, esto es un problema, vea la respuesta a Q2.
Q2: 1 y 2 no están definidos ya que se refieren a variables locales en la pila de getA1 y getA2. Esas variables están fuera del alcance y ya no están disponibles y se puede sobrescribir lo peor, ya que la pila cambia constantemente. getA3 funciona ya que se crea una copia del valor de retorno y se devuelve a la persona que llama.
P3: No existe tal garantía para ver la respuesta a Q2.
Si compila esto en VC6 obtendrá esta advertencia
****** Advertencia del compilador (nivel 1) C4172 dirección de retorno de la variable local o temporal Una función devuelve la dirección de una variable local o un objeto temporal. Las variables locales y los objetos temporales se destruyen cuando se devuelve una función, por lo que la dirección devuelta no es válida. ******
Mientras probaba este problema encontré algo interesante (dado que el código está funcionando en VC6):
class MyClass
{
public:
MyClass()
{
objID=++cntr;
}
MyClass& myFunc()
{
MyClass obj;
return obj;
}
int objID;
static int cntr;
};
int MyClass::cntr;
main()
{
MyClass tseadf;
cout<<(tseadf.myFunc()).objID<<endl;
}