참조자(Reference)
참조자(Reference)
C++ 에서 참조자는 변수의 또 다른 이름을 제공하는 방법이다.
참조자는 기존 변수에 대한 별칭(alias)이며, 변수와 동일한 메모리 위치를 가리킨다.
참조자는 포인터와 유사한 개념이지만, 포인터와는 다른 동작 방식을 가진다.
참조자를 정의하려면 아래의 코드 처럼 데이터 타입& 변수명 = 변수; 를 사용하면 된다.
int num1 = 1020; // num1주소 100번지
int& num2 = num1; // num2주소 100번지
num2 = 3040;
cout << "VAL: " << num1 << endl; // 3040
cout << "REF: " << num2 << endl; // 3040
cout << "VAL: " << &num1 << endl; // 100번지
cout << "REF: " << &num2 << endl; // 100번지
참조자를 사용하면 변수에 대한 별칭을 생성하여 해당 변수에 직접 접근할 수 있다.
참조자는 변수에 대한 포인터로 생각할 수도 있지만, 결정적인 차이가 존재한다.
포인터는 널(null)값을 가질 수 있고, 포인터 변수를 다른 변수로 변경할 수 있다.
그러나 참조자는 반드시 초기화해야 하며, 한 번 참조된 변수를 다른 변수로 변경할 수 없다.
즉, 참조자는 항상 참조한 변수를 가리키게 된다.
레퍼런스는 메모리 공간을 공유하지만, 포인터는 새로운 메모리 공간을 할당받고,
그 공간에 주소를 참조하는 방식이다. 즉 레퍼런스 연산자는 할당되는 메모리 공간이
무조건 필요해서 선언과 동시에 초기화를 해줘야 한다.
아래의 코드처럼 널 값이 필요할 때는 포인터 연산자를 사용하고
널 값이 필요없는 경우는 레퍼런스연산자를 사용하면 된다.
int& num1; // 컴파일 에러
int& num2 = NULL; // 컴파일 에러
int* num3; // 컴파일 성공
int* num4 = NULL; //컴파일 성공
참조자는 함수의 매개변수로 사용될 때 특히 유용하다.
함수에 매개변수로 참조자를 사용하면 원본 변수에 대한 복사본을
생성하지 않고도 함수 내에서 변수를 수정할 수 있다.
함수 호출 시간과 메모리 사용을 절약할 수 있다.
참조자 활용
참조자는 C++에서 많은 곳에서 사용되며, 변수 별칭 생성, 함수 매개변수 전달,
연산자 오버로딩 등 다양한 상황에서 유용하다. 그러나 참조자는 주의해서 사용해야 한다.
참조자를 잘못 사용하면 예상하지 못한 동작이 발생할 수 있다.
참조자 주의사항
참조자는 선언과 동시에 초기화해줘야 하며, 그 이후에는 다른 변수로
변경이 불가능하다. 즉, 참조자는 참조한 변수를 계속 참조하게 된다.
아래의 코드는 이와 관련된 예제이다.
int x = 5;
int y = 10;
int& ref = x;
ref = y; // x의 값이 10으로 변경됨
위의 코드는 ref참조자가 x의 메모리 공간을 공유하게 된다.
그 밑에서 ref에 y를 할당해준다. 이러면 ref참조자가 y의 메모리 공간을
공유할거라 생각할 수도 있지만, 실상은 ref가 참조하는 x의 메모리 공간에
y의 데이터 값을 할당해주는 꼴이 됩니다.