Aliasing (Reference Variable)
기본적으로, 우리가 선언된 변수를 다른 변수에 할당하게 되면 이 값을 복사해서 사용하는 셈이 된다.
작은 값의 경우 복사를 해서 프로그램을 짜는 것이 문제가 없을 수 있지만, 구조체나 객체같은 경우 복사를 해서 쓴다면 메모리 낭비가 될 수 있다.
또한, 함수의 인자로 값을 그냥 넘겨준다면, 그 함수 내에서만 선언되는 지역변수들만 가지고 장난을 치게되어, 내가 원하는 결과, 원래 값 자체를 가지고 반환하는 것, 이 도출되지 않을 수 있다.
그렇기 때문에 우리는 내가 저장한 값 자체를 가리킬 필요성이 생기는데, C에서는 이걸 Pointer 로 가능하게 했었다.
하지만 포인터의 문제점 때문에, C++ 은 참조변수라는 새로운 개념을 도입한다.
포인터와 참조변수의 차이점과 장단점은 밑에서 다뤄보도록 하고, 지금은 참조변수에 대해서 알아보자.
int x = 3;
int &r = x;밑의 &r 이 참조 변수이다. 저렇게 할 경우 r은 x가 저장된 메모리공간을 동시에 가르키는 변수이다.
즉, x가 가리키는 3의 별명 이 생겼다고 생각하면 된다.
Example
#include <iostream>
int main(){
int x = 5;
int y = x;
int &r = x;
std::cout << "x = " << x << '\n';
std::cout << "y = " << y << '\n';
std::cout << "r = " << r << '\n';
x = 7;
std::cout << "---------------" << endl;
std::cout << "x = " << x << '\n';
std::cout << "y = " << y << '\n';
std::cout << "r = " << r << '\n';
return 0;
}출력
// x = 5
// y = 5
// r = 5
// ---------------
// x = 7
// y = 5
// r = 7x 값을 바꿨더니, r에는 바뀐 값이 들어간 것을 볼 수 있다. 반대로 y는 5라는 값이 그대로 들어가 있다.
y는 x값을 복사해서 메모리에 넣은 것이고, r은 x의 메모리공간을 함께 뜻하고 있음을 알 수 있다.
여기서 여러 혼란이 올 수 있다.
- C에서는
&는 저장된 값의 주소를 불러오는 방법이었다. 그런데 여기서는 참조변수라는 다른 이름을 가져다가 쓰고 있다. - 같은 값을 가리킨다는 점에서 C언어에서 Pointer 가 생각났다. 그런데 애매하게 다른 점이 있는 것 같다.
구체적으로 어떤점이 다를까?
Comparision
참조변수는 내가 선언한 값을 동시에 가리킨다는 점에서 포인터와 유사한 측면이 있다.
또 헷갈리는 점은, C에서 &의 사용은, 내가 저장한 변수의 주소값을 불러오는 용도로 사용했었다.
그런데 C++에 와서는 이녀석을 참조변수로 사용할 수 있다고 하니 여간 혼동스러운게 아니다.
Difference between Pointer & Reference Variable
C에서 포인터는 장단점이 아주 명확하다.
- 장점 : 메모리에 직접적으로 접근할 수 있다.
- 단점 : 그렇기 때문에 사용자의 선택이 지배적이다. 즉, 아무렇게나 접근하여 잘못된 주소로 접근할 수 있다는 위험성이 있다.
포인터의 문제점은 선언과 할당을 나누기 때문에 발생한다.
#include <stdio.h>
int main(){
int x;
int *a;
x = 4;
*a = x;
return 0;
}위와 같은 방식으로 선언과 할당을 해준다.

이런식으로 가리키게 된다. 그런데 만약 내가 이것보다 복잡한 구조에서 포인터를 잘못사용한다면 NULL 또는 Garbage 값이 들어갈 위험이 있다.
이런 단점을 보안하는 방식으로 참조변수 가 만들어졌다.
#include <iostream>
int main(){
int x = 4;
int &r = x;
return 0;
}이렇게 사용할 경우
r은 x를 가리키는 또다른 별칭이 된다.

이런식으로 구성된다. 참조변수는 포인터와 다르게 선언과 할당이 분리되어서 사용되지 않고, 동시에 이루어져야 한다.
즉, 선언과 초기화가 동시에 이루어진다. 그렇기 때문에 포인터에서 발생하는 잘못된 객체를 가리키는 문제점이 해결된다.
Summary
Pointer
- 선언과 할당이 분리되어 이루어짐
- 자유롭게 객체를 가리킬 수 있으나, 그렇기 때문에 오류 발생확률이 높음 (Null 값)
- 선언과 할당이 분리되니, 포인터 변수안의 주소값을 바꿀 수 있음
- 포인터 변수안에는 해당 객체의 주소값이 들어가있음
*를 사용해서 선언하고 사용함
Reference Variable
- 선언과 할당이 동시에 이루어짐
- 그렇기 때문에 포인터에 비해 오류가 날 확률이 줄어듦
- 또한 선언과 할당이후 다른 객체를 가리킬 수 없음
- 참조변수는
x값 자체를 가리킴 x의 별칭이라고 생각하면 됨&을 사용해서 선언하고 사용함
주소를 가져오는 & 와 참조변수의 &
C 에서 scanf() 같은 함수를 사용할 때, &a 와 같은 방식으로 입력을 받았다.
이 때, &는 변수의 주소를 가져오는 방법으로 생각하고 사용했었다.
같은 &를 쓰면서 왜 하나는 주소를 가져오는 방법으로, 또 참조변수라고 다르게 얘기하는 걸까?
사용법은 2가지가 있는데, 구체적으로 알아보면 굉장히 간단함을 알 수 있다. 차례차례 알아보자.
주소를 가져오는 &
#include <stdio.h>
int main(){
int x;
int *a;
a = &x;
return 0;
}이 코드를 보면, a 는 x 의 주소를 받음을 알 수 있다. 이때 &은 참조변수가 아니고 x의 주소를 가져온다.
"=" 연산자의 오른쪽 에 있는 것을 기억하자.
참조변수 &
#include <iostream>
int main(){
int x = 4;
int &a = x;
return 0;
}c++ 에서 참조변수는 다음과 같이 선언과 초기화를 한다.
이때 &는 = 연산자 왼쪽 에 있다.
Summary
결국 주소를 가져올 때 & 는 오른쪽 참조변수를 사용할 때는 왼쪽 에 있다.