Pergunta

Greetings, todos!

Examinando meu próprio código, eu vim a esta linha interessante:

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

Agora estou completamente perdido, e não consegue entender por que ela é legal. Tanto quanto eu compreender, const referência deve ser inicializada, quer com o valor de r ou l-valor. referências não inicializadas não pode existir. Mas ()? operador executa uma função CheckCondition () antes de ele atribui valor para a referência. Eu posso ver agora que, enquanto CheckCondition () é executado, refStr existe, mas ainda não inicializado. O que acontecerá se CheckCondition () irá lançar uma exceção, ou passar o controle com uma instrução goto? Será que vai deixar a referência inicializada ou estou faltando alguma coisa?

Foi útil?

Solução

exemplo mais simples: const int x = foo();

Esta constante também tem de ser inicializado, e para isso foo() precisa ser chamado. O que acontece no fim necessário:. X entra em existência apenas quando foo retorna

Para responder às suas perguntas adicionais: Se foo() seria throw, a exceção será capturado por um algum lugar catch(). O bloco try{} para que catch() rodeado const int x = foo(); obviamente. Daí const int x está fora do escopo já, e é irrelevante que nunca tem um valor. E se não há nenhuma catch para a exceção, o seu programa (incluindo const int x) está desaparecido.

não

C ++ não tem aleatório goto de. Eles podem saltar dentro foo() mas isso não importa; foo() ainda tem de voltar.

Outras dicas

Está faltando alguma coisa - é totalmente código legal, e na verdade esse código é um dos usos mais comuns e melhores do operador condicional. É sempre um erro pensar que o compilador deve fazer internamente as coisas na mesma ordem que o código é Definiu na página - é perfeitamente livre para avaliar o operador condicional (que é Justv outra expressão) e, em seguida, utilizar o resultado para executar a inicialização.

Quanto a um goto, não há nenhuma maneira de usar um em uma inicialização. E se uma exceção é lançada, a referência é considerado nunca ter sido criado em primeiro lugar.

referências não inicializadas não pode existir.

Infelizmente coisas engraçadas pode ser feito durante a inicialização. Você também poderia ter escrito

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

ou para o assunto

const int& a = a;

suponho como o compilador procede da esquerda para a direita, um é de fato no âmbito do lado direito, então tecnicamente , você deve ser capaz de usá-lo e na melhor das hipóteses ele pode avisar:

"ComeauTest.c", a linha 9: warning: variável "a" é usado antes seu valor é definido

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

Naturalmente, isso só pode resultar em um comportamento indefinido como com o uso de qualquer variável não inicializada.

O seu exemplo é bom, desde que você não usar a referência antes de ter sido inicializado.

Eu posso ver agora que, enquanto CheckCondition () é executado, refStr existe, mas ainda não inicializado.

Do ponto advogado de vista da linguagem, isso é errado. Durante a inicialização, refStr ainda não existe. Eu acho que o depurador visual é dando-lhe enganosa dicas.

Se o código dentro das pistas de inicialização para uma condição de erro, refStr não vai existir, e não irá nunca ter existido.

Esta é completamente legal. Ou este for concluído com êxito e a referência é vinculado a um objeto válido ou uma exceção é lançada e controle é transferido fora do bloco ea referência não está no escopo de modo cuidados Noone de mais.

Uma exceção levará para um lugar onde refStr não é acessível e você não pode ir para um lugar onde ele é de lá. A Goto não será capaz de sair da CheckCondition () se for uma função, e você não será capaz de usar um goto se é uma macro. A longjmp () terá o mesmo efeito que uma exceção:. Você vai para um lugar onde refStr não é acessível

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top