Development Tip

C ++에서 참조를 재 할당 할 수 있습니까?

yourdevel 2020. 12. 1. 19:49
반응형

C ++에서 참조를 재 할당 할 수 있습니까?


참조가 초기화되어야하고 다시 초기화 될 수 없다는 것을 모든 곳에서 읽었습니다.

이해를 테스트하기 위해 다음과 같은 작은 프로그램을 작성했습니다. 실제로 참조를 다시 할당하는 데 성공한 것 같습니다. 누군가 내 프로그램에서 실제로 무슨 일이 일어나고 있는지 설명해 줄 수 있습니까?

#include <iostream>
#include <stdio.h>
#include <conio.h>

using namespace std;

int main()
{
    int i = 5, j = 9;

    int &ri = i;
    cout << " ri is : " << ri  <<"\n";

    i = 10;
    cout << " ri is : " << ri  << "\n";

    ri = j; // >>> Is this not reassigning the reference? <<<
    cout << " ri is : " << ri  <<"\n";

    getch();
    return 0;
}

코드가 잘 컴파일되고 출력은 예상대로입니다.

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

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

아니요, ri여전히 참조입니다. i인쇄 &ri하고 &i동일한 주소 임을 확인하여이를 증명할 수 있습니다 .

당신이 한 일은 참조를 i 통해 수정 하는 것 ri입니다. i나중에 인쇄 하면 이것을 볼 수 있습니다.

또한 비교를 위해 생성 const int &cri = i;하면 할당 할 수 없습니다.


실제로 참조를 다시 할당하는 데 성공한 것 같습니다. 사실인가요?

아니 , 당신은하지 않았습니다. 실제로 값을 다시 할당하고 참조를 다시 바인딩하지 않습니다.

당신이 할 때의 예에서 int &ri = i;, ri결합되어 i수명을 위해. 이렇게하면 ri = j;의 값을 j할당하는 ri입니다. ri여전히 i! 그리고 그것은 당신이 대신 쓴 것처럼 같은 결과를 가져옵니다.i = j;

포인터를 잘 이해한다면 항상 참조를 T* const어디에 T어떤 유형 있는지에 대한 유 추적 해석으로 생각하십시오 .


참조에 무언가를 할당 할 때 실제로 참조가 바인딩 된 객체에 값을 할당합니다. 그래서 이건:

ri=j;

다음과 같은 효과가 있습니다.

i = j;

ri바인딩되어 있기 때문에 가질 것 i입니다. 따라서의 모든 작업 ri은에서 실행됩니다 i.


를 실행할 때 참조를 다시 할당하지 않습니다 ri = j;. 실제로에 할당 j하고 i있습니다. i줄 뒤에 인쇄 시도 하면 i변경된 값을 볼 수 있습니다.


OP는 참조에 대한 할당을 통해 참조 된 객체를 변경하도록 요청했으며 이것이 참조가 아닌 참조 객체를 변경했다고 매우 정확하게 들었습니다. 이제 실제로 참조를 변경하려고 더 신랄한 시도를했고 잠재적으로 불쾌한 것을 발견했습니다. 먼저 코드입니다. 새로 생성 된 객체를 참조 var에 재 할당하려고 시도한 다음 참조 (일명 참조 객체)를 변경하고 이것이 명백하게 참조 된 객체에 반영되지 않음을 발견하고 C ++에서 댕글 링 포인터의 경우가있을 수 있다는 결론을 내립니다. 성급하게 작성된 코드에 대해 죄송합니다.

using namespace std;
vector<int>myints;

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;

산출:

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

결론 : 적어도 내 경우 (VS2017)에서는 참조가 메모리에 정확히 동일한 주소를 유지했지만 참조 된 값 (벡터의 일부)은 다른 곳에서 재 할당되었습니다. 참조 내가 매달려있을 수 있습니다.

참고URL : https://stackoverflow.com/questions/9293674/can-we-reassign-the-reference-in-c

반응형