Podemos reatribuir a referência em C ++?

Eu li em todos os lugares que uma referência precisa ser inicializada e não pode ser reinicializada novamente.

Para testar meu entendimento, escrevi o seguinte pequeno programa. Parece que, na verdade, consegui reatribuir uma referência. Alguém pode me explicar o que realmente está acontecendo no meu programa?

#include  #include  #include  using namespace std; int main() { int i = 5, j = 9; int &ri = i; cout << " ri is : " << ri <<"\n"; i = 10; cout << " ri is : " << ri <>> Is this not reassigning the reference? <<< cout << " ri is : " << ri <<"\n"; getch(); return 0; } 

O código compila bem e a saída é como eu esperava:

 ri is : 5 ri is : 10 ri is : 9 

ri = j; // >>> Is this not reassigning the reference? <<<

Não, o ri ainda é uma referência para i - você pode provar isso imprimindo &ri e &i e vendo que eles são o mesmo endereço.

O que você fez foi modificar i através do ri referência. Imprimir i depois, e você verá isso.

Além disso, para comparação, se você criar um const int &cri = i; não vai deixar você atribuir a isso.

Parece que, na verdade, consegui reatribuir uma referência. Isso é verdade?

Não , você não tem. Você está, na verdade, reatribuindo o valor e não está vinculando novamente a referência.

No seu exemplo, quando você faz int &ri = i; , ri está ligado a i por sua vida. Quando você faz ri = j; , você está simplesmente atribuindo o valor de j para ri . ri ainda continua sendo uma referência para i ! E isso resulta no mesmo resultado como se você tivesse escrito i = j;

Se você entender bem os pointers, sempre pense na referência como uma interpretação analógica de T* const que T é qualquer tipo.

Quando você atribui algo a uma referência, você realmente atribui o valor ao object ao qual a referência está vinculada. Então, é isso:

 ri=j; 

tem o mesmo efeito que

 i = j; 

teria porque ri está ligado a i . Portanto, qualquer ação no ri é executada em i .

Você não está reatribuindo a referência ao executar ri = j; . Você está realmente atribuindo j para i . Tente imprimir depois da linha e você verá que i mudei o valor.

OP solicitou a alteração do object referenciado através da atribuição à referência e foi corretamente informado que isso alterou o object de referência, não a referência. Agora eu fiz uma tentativa mais pungente de realmente mudar a referência e encontrei coisas potencialmente desagradáveis. Primeiro o código. Ele tenta reatribuir a referência var um object recém-criado, em seguida, altera a referência aka object referenciado, descobre que isso não é refletido nos objects aparentemente referenciados e conclui que podemos ter um caso de um ponteiro pendente em C ++. Desculpe pelo código composto apressadamente.

 using namespace std; vectormyints; auto &i = myints.emplace_back(); // allocate and reference new int in vector auto myintsaddr = &myints; auto myintfrontaddr = &myints.front(); // for future reference i = 1; // assign a value to the new int through reference cout << hex << "address of i: 0x" << &i << " equals " << "address of myints.back(): 0x" << &myints.back() << '.' << endl; // check reference as expected i = myints.emplace_back(); // allocate new int in vector and assign to old reference variable i = 2; // give another value to i cout << "i=" << i << ", myints={" << myints[0] << ", "<< myints[1] << '}' << endl; // any change to potentially referenced objects? cout << hex << "&i: 0x" << &i << " unequal to " << "&myints.back(): 0x" << &myints.back() << " as well as &myints.front(): 0x" << &myints.front() << endl; cout << "Myints " << (myintsaddr== &myints?"not ":"") << "relocated from " << myintsaddr << " to " << &myints << endl; cout << "Myints front() " << (myintfrontaddr == &myints.front() ? "not " : "") << "relocated from " << myintfrontaddr << " to " << &myints.front() << endl; 

Saída:

 address of i: 0x0063C1A0 equals address of myints.back(): 0x0063C1A0. i=2, myints={1, 0} &i: 0x0063C1A0 unequal to &myints.back(): 0x0063F00C as well as &myints.front(): 0x0063F008 Myints not relocated from 0039FE48 to 0039FE48 Myints front() relocated from 0063C1A0 to 0063F008 

Conclusão: pelo menos no meu caso (VS2017) a referência manteve exatamente o mesmo endereço na memory, mas os valores referenciados (parte do vetor) foram realocados em outro lugar. Referência eu posso estar pendurado.