variable validar validacion una inicializar inicializa hacer datos como codigo campos c++ constructor reference const

validar - Constructor C++: basura mientras se inicia la referencia de const



validar codigo c++ (4)

Dejaré que mi compilador responda este:

$ g++ -std=c++98 -Wall -Wextra -pedantic test.cpp test.cpp: In constructor ''X::X()'': test.cpp:9:26: warning: a temporary bound to ''X::b'' only persists until the constructor exits [-Wextra] $

Deberías activar las advertencias en tu compilador también.

¿Qué pasa con este código? ¿Por qué recibo una respuesta incorrecta?

class X { private: const int a; const int& b; public: X(): a(10) , b(20) { // std::cout << "constructor : a " << a << std::endl; // std::cout << "constructor : b " << b << std::endl; } void display() { std::cout << "display():a:" << a << std::endl; std::cout << "display():b:" << b << std::endl; } }; int main(void) { X x; x.display(); return 0; }

El código anterior me dará el resultado como

display():a:10 display():b:1104441332

Pero si elimino las 2 líneas comentadas dentro del constructor predeterminado, me da el resultado correcto que es

constructor : a 10 constructor : b 20 display():a:10 display():b:20

por favor ayuda, gracias


Estás vinculando el const& a un temporal, que no vive más allá de la llamada al constructor. El estándar C ++ 03 dice específicamente "un límite temporal a un miembro de referencia en el inicializador de ctor de un constructor (12.6.2) persiste hasta que el constructor salga" (12.2 / 5 "Objetos temporales").

Por lo tanto, su código tiene un comportamiento indefinido; es posible que no tenga sentido o que parezca que está "funcionando".

FWIW, MSVC 2010 da la siguiente advertencia en ese código:

C:/temp/test.cpp(12) : warning C4413: ''X::b'' : reference member is initialized to a temporary that doesn''t persist after the constructor exits


b refiere a un temporal. Lo que ha leído (al imprimir) es una ubicación no válida en el momento en que se lee, ya que técnicamente el 20 temporal ha salido del alcance.

Para explicar resultados inconsistentes:

Es un comportamiento indefinido. Lo que ves puede ser diferente si tú:

  • cambia tu compilador
  • cambiar la configuración de tu compilador
  • construir para otra arquitectura
  • cambia el diseño de miembros de tu clase
  • agrega o elimina cosas de la región de la memoria cerca de la instancia de x
  • etc.

Siempre debes siempre evitar el comportamiento indefinido.

Pero, ¿por qué cambiaría el valor? Su referencia probablemente se refiere a una dirección de pila que ha sido reescrita (por ejemplo, reutilizada) para el momento en que se imprime.


Está inicializando b como una referencia a un temporal .

El valor 20 se crea y existe solo para el alcance del constructor.

El comportamiento del código después de esto es muy interesante: en mi máquina, obtengo valores diferentes de los que publicó, pero el comportamiento fundamental sigue siendo no determinista.

Esto se debe a que, cuando el valor al cual los puntos de referencia quedan fuera del alcance, comienza a hacer referencia a la memoria basura, lo que le da un comportamiento impredecible.

Ver ¿Una referencia constante prolonga la vida de un temporal? ; la respuesta https://.com/a/2784304/383402 enlaza con la sección relevante del estándar C ++, específicamente el siguiente texto:

A temporary bound to a reference member in a constructor’s ctor-initializer (12.6.2) persists until the constructor exits.

Esta es la razón por la que siempre obtienes el valor correcto en la impresión dentro del constructor, y raramente (¡pero posiblemente a veces!) Después. Cuando el constructor sale, la referencia cuelga y todas las apuestas están desactivadas.