1. 참조자(Reference)


참조자(Reference, 레퍼런스)는 간단히 말하면 변수에 또 하나의 별명을 붙여주는 녀석입니다. 할당된 어느 메모리 공간에 이름에, 둘 이상의 이름을 부여하는 것이므로 대상이 이름이 존재하지 않을 경우에는 역시, 참조할 수 없습니다. 간단히 a란 변수에 aa라는 별명을 붙여주어 보도록 하겠습니다.

int a=50;
int &aa=a;

위를 보시면, a라는 변수를 선언과 동시에 50이란 값으로 초기화 되었고, 그 아래의 aa란 녀석에 a가 대입되었습니다. 한가지 특이한 점은 aa의 이름 앞에 &(주소 반환) 연산자가 붙는다는 것입니다. 이 주소 반환 연산자는 우리가 C언어에서 포인터를 공부할 때 한번 본 기억이 있죠? 물론, 변수 앞에 & 연산자가 붙으면 그 변수의 주소값을 반환합니다. 위와 같이 변수 선언 앞에 & 연산자가 쓰이면 이는, 참조자 선언이 됩니다. 한가지 주의하실 점은, 참조자는 선언 시에 반드시 초기화하여야 한다는 겁니다. 그리고, 한번 초기화 되고 나서는 다른 변수를 참조할 수 없습니다.


한번, 참조자를 직접 사용해보도록 하겠습니다. 아래는 참조자를 사용하여 num이란 변수에 num1이란 별칭을 붙여주고, 두 변수의 주소값을 확인해보았습니다.

#include <iostream>

using namespace std;

int main()
{
	int num=50;
	int &num1 = num;

	cout << "num: " << &num << endl;
	cout << "num1: " << &num1 << endl;
	return 0;
}

결과:

num: 0097F76C

num1: 0097F76C

계속하려면 아무 키나 누르십시오 . . .


보시면 알겠지만, 참조자 num1은 num를 참조하고 있고, 두 변수는 같은 메모리 공간을 가르키고 있습니다. 그렇다면, num이 아닌 참조자 num1을 대상으로 값을 대입하면 num의 값이 바뀔까요? 네, 물론입니다. 앞서 말한 그대로, 두 변수는 '같은 메모리'공간을 가르키고 있습니다. num1은 num을 부르는 또다른 이름이라고 생각하시면 됩니다. 또 하나의 특징으로는, 실제로 어떤 친구의 별명이 여러개이듯, C++에서도 같은 변수를 참조하는 여러개의 참조자를 선언할 수 있습니다. 그리고 참조자를 대상으로 참조자를 선언하는 것도 역시 가능합니다.

#include <iostream>

using namespace std;

int main()
{
	int num=50;
	int &num1 = num;
	int &num2 = num;
	int &num3 = num2;

	cout << "num: " << &num << endl;
	cout << "num1: " << &num1 << endl;
	cout << "num2: " << &num2 << endl;
	cout << "num3: " << &num3 << endl;
	return 0;
}

결과:

num: 0043FCB0

num1: 0043FCB0

num2: 0043FCB0

num3: 0043FCB0

계속하려면 아무 키나 누르십시오 . . .


코드를 보시면 8~10행에 참조자가 선언됬고, 8행~9행은 num를 참조하지만, num3은 num2를 참조합니다. num2는 num을 참조하고 있으므로, num3도 num를 참조하게 되는거죠. 결과를 보시면 네 변수다 똑같은 주소값을 출력합니다.


2. 참조자를 이용한 Call by reference


우리는 이미 C언어의 포인터를 공부하다 Call by value(값에 의한 호출)와 Call by reference(참조에 의한 호출)을 이미 본적이 있습니다. 기억이 안나시면 아래 링크의 11-6을 참고하세요. 

(11-6 Call-By-Value 그리고 Call-By-Reference: http://blog.eairship.kr/18)


제목 그대로, 참조자를 사용해서 Call by reference(참조에 의한 호출)이 가능합니다. a와 b의 값을 서로 바꾸는 swap 함수를 참조자를 이용해 작성해보도록 하겠습니다.

#include <iostream>

using namespace std;

void Swap(int &ref1, int &ref2)
{
	int temp = ref1;
	ref1 = ref2;
	ref2 = temp;
}

int main()
{
	int a = 50, b = 40;

	cout << "swap before, a: " << a << " b: " << b << endl;
	Swap(a, b);
	cout << "swap after, a: " << a << " b: " << b << endl;
	return 0;
}

결과:

swap before, a: 50 b: 40

swap after, a: 40 b: 50

계속하려면 아무 키나 누르십시오 . . .


5행을 보시면 매개변수에 참조자가 위치합니다. 우선 넘겨두고, 16~18행에 주목하도록 합시다. 16행에선 당연히 기존의 a와 b의 값을 출력합니다. (50, 40) 17행에서 Swap 함수가 호출되며, a와 b가 Swap 함수로 넘어가는데, 이렇게 넘어오면서 참조자 ref1와 ref2가 초기화되고, ref1은 a를 가르키며 ref2는 b를 가르킵니다. 함수 내에서 temp 변수에 ref1(a)값을 넣어두고, ref1(a)에 ref2(b)값을 넣고, ref2(b)에 temp값을 넣어 두 값이 서로 바뀝니다. 18행에서 바뀐 값을 확인하실 수 있습니다.


이제 참조자에 대한 설명은 여기서 그만 마치도록 하겠습니다. 여기까지 보느라 수고하셨고, 다음 강좌는 friend에 대해 알아보도록 하겠습니다.