Pregunta

Saludos a todos!

Al examinar mi propio código, se me ocurrió a esta interesante línea:

const CString &refStr = ( CheckCondition() ) ? _T("foo") : _T("bar");

Ahora estoy completamente perdido, y no puedo entender por qué es legal. Por lo que entiendo, la referencia const debe ser inicializado, ya sea con r-valor o l-valor. no pueden existir sin inicializar referencias. Pero ()? operador ejecuta una función CheckCondition () antes de que se asigna valor a la referencia. Puedo ver ahora, que mientras se ejecuta CheckCondition (), existe refStr, pero aún no se ha iniciado. ¿Qué pasará si CheckCondition () lanzará una excepción, o pasar el control con una instrucción goto? ¿Dejará la referencia sin inicializar o estoy perdiendo algo?

¿Fue útil?

Solución

ejemplo más sencillo: const int x = foo();

Esta constante también tiene que ser inicializado, y por esa foo() necesita ser llamado. Eso sucede en el orden necesario:. X llega a existir sólo cuando vuelve foo

Para responder a sus preguntas adicionales: Si foo() sería throw, la excepción será capturado por un catch() en alguna parte. El bloque try{} para que catch() rodeado const int x = foo(); obviamente. Por lo tanto const int x está fuera del alcance ya, y es irrelevante que nunca tiene un valor. Y si no hay catch para la excepción, su programa (incluyendo const int x) se ha ido.

C ++ no tiene aleatorias de goto. Pueden saltar dentro foo() pero eso no importa; foo() todavía tiene que devolver.

Otros consejos

Se le falta algo - es totalmente código legal, y de hecho tal código es uno de los usos más comunes y mejor del operador condicional. Siempre es un error pensar que el compilador debe hacer internamente las cosas en el mismo orden que el código está organizada en la página - es perfectamente en libertad para evaluar el operador condicional (que es justV otra expresión) y luego usar el resultado de realizar la inicialización.

En cuanto a un Goto, no hay manera de utilizar uno en una inicialización. Y si se produce una excepción, la referencia se considera que nunca ha sido creado en el primer lugar.

  

no pueden existir sin inicializar referencias.

Desafortunadamente cosas divertidas se pueden realizar durante la inicialización. También podría haber escrito

const int& a = foobar(a) ? 1 : 2;

o para la materia

const int& a = a;

supongo medida que avanza el compilador de izquierda a derecha, es de hecho un alcance en el lado derecho, por lo que técnicamente que debe ser capaz de utilizarlo y en el mejor puede advertir:

"ComeauTest.c", línea 9: advertencia: variable "a" se usa antes de que se establezca su valor

  const int& a = foobar(a) ? 1 : 2;
                        ^

Naturalmente, esto sólo puede resultar en un comportamiento indefinido como con el uso de cualquier variable sin inicializar.

Su ejemplo está muy bien, ya que no utiliza la referencia antes de que se haya inicializado.

  

Ahora puedo ver, que mientras se ejecuta CheckCondition (), existe refStr, pero aún no se ha iniciado.

Desde el punto de vista abogado lenguaje, esto es un error. Durante la inicialización, refStr no existe todavía. Supongo que su depurador visual le está dando consejos engañosos.

Si el código dentro de la inicialización conduce a una condición de error, no existirá refStr, y no haber existido jamás.

Esto es completamente legal. O este finaliza correctamente y la referencia está enlazado a un objeto válido o se produce una excepción y el control se transfiere fuera del bloque y la referencia ya no está en el ámbito de modo nadie se preocupa de más.

Una excepción le llevará a un lugar donde refStr no es accesible y no puede ir a un lugar donde es desde allí. Un Goto no será capaz de salir de CheckCondition () si se trata de una función, y usted no será capaz de utilizar un Goto si se trata de una macro. Un longjmp () tendrá el mismo efecto que una excepción:. Que va a ir a un lugar donde no es accesible refStr

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top