C를 학습할 때, *는 포인터 혹은 포인터 안의 값, &는 변수의 주소를 의미한다고 배웠을것이다.
근데 cpp를 해보니 거기서도 int& a같이 쓰는데 또 이는 레퍼런스라고 한다. 도대체 뭘까 해서 찾아보니, 그냥 쓰기 나름인거였다.
레퍼런스란, 쉽게 설명해서 특정 변수의 별명같은것이다.
int main() {
int a = 5;
int& b = a;
}
같은 코드가 있을때, a는 5라는 값을 가지고, 레퍼런스 b는 a의 를 나타내는 또 다른 말이 된다.
만약 b = 3같은 코드를 집어넣고 a를 출력해보면 3이라고 나올것이다.
b변수 주소가 a값의 주소를 공유한다고 생각하면 될듯하다.
# include <iostream>
int main() {
int a = 5;
int b = 3;
}
다음과 같은 코드에서 두 값을 바꾸고 싶다고 하자, python이라면 a, b = b, a 같은 초간단 코드로 해결할 수 있지만, 주소와 포인터개념이 있는 cpp에서는 그렇지 않다.
void swap(int a, int b) {
int temp = a;
a = b;
b = temp;
}
다음과 같이 작성하면어떨까?
이는 그럴듯해 보이지만, 실제로는 함수 내부에서만 그 값이 바뀌고 밖에서는 그대로 값을 가지게 된다. 따라서 우리는 레퍼런스를 이용해서 값을 직접 불러와야한다. (c에서는 주소호출이라고 했었다)
void swap(int &a, int &b) {
int temp = a;
a = b;
b = temp;
}
다음과 같은 코드르 이용하면 함수는 레퍼런스, 즉 해당 인자의 진짜 주소에 접근하게 되고 그 값을 바꾸는것이다.
만약 레퍼런스를 받았지만 값이 바꿔서는 안된다면,
void swap(const int &a, const int &b) {
int temp = a;
a = b;
b = temp;
}
const화 하여 상수처리하면 변수값 변경이 불가능하게 된다.
또한 지역변수는 레퍼런스로 리턴할 수 없다. 함수가 끝나면 지역변수가 사라지면서, 레퍼런스가 포인팅할게 없어지기 때무이다.
# include <iostream>
int& func() {
int a = 10;
return a;
}
int main() {
int &ref = func();
std::cout << ref << std::endl;
return 0;
}
다음과 같은 코드를 사용하게 되면, 오류가 난다.
warning: reference to local variable 'a' returned
# include <iostream>
int func() {
int a = 10;
return a;
}
int main() {
int ref = func();
std::cout << ref << std::endl;
return 0;
}
다음과 같이 작성하면 정상적으로 ref가 값을 가진다.
int &ref도 안되는데 이는 레퍼런스할 값이 없기 떄문이다. (a는 사라진다)