todas - void c++ ejemplo




Devolver la referencia constante a la variable local de una función (3)

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 =>

  1. ¿Es correcta la implementación de getA1() ? Siento que es incorrecto ya que devuelve la dirección de una variable local o temporal.

  2. ¿Cuál de las afirmaciones en main (1,2,3) conducirá a un comportamiento indefinido?

  3. 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?


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 referencia const 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.


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/…


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;

}




const-reference