참조자와 함수
이전 글에서 단순히 변수에 별칭을 붙여주는 것으로 예를 들었는데, 참조자는 보통 함수에서 사용할 때 큰 장점을 보인다.
값을 변경하는 Swap 함수를 Call-by-value의 형태로 정의하면 아래와 같다.
#include <iostream>
using namespace std;
void Swap(int val1, int val2) {
	int temp = val1;
	val1 = val2;
	val2 = temp;
}
int main() {
	int val1 = 5;
	int val2 = 10;
	Swap(val1, val2);
	cout << "val1 : " << val1 << endl;
	cout << "val2 : " << val2 << endl;
	return 0;
}Swap 함수의 매개변수에는 값이 복사되기 때문에 val1과 val2의 값은 서로 바뀌지 않는다.
하지만 참조자를 이용하여 Call-by-reference의 함수 호출을 진행하면 두 값이 서로 바뀌는 것을 볼 수 있다.
#include <iostream>
using namespace std;
void Swap(int &ref1, int &ref2) {
	int temp = ref1;
	ref1 = ref2;
	ref2 = temp;
}
int main() {
	int val1 = 5;
	int val2 = 10;
	Swap(val1, val2);
	cout << "val1 : " << val1 << endl;
	cout << "val2 : " << val2 << endl;
	return 0;
}매개변수로 값을 넘길 때, int &ref1 = val1; 이 실행된다고 생각하면 쉽다.
ref1과 ref2는 또 다른 메모리에 할당된 변수가 아닌, val1, val2의 다른 이름이므로 실제로 값 복사가 이뤄진다.
반환형이 참조형인 경우
반환형을 참조형으로 정의하는 것도 가능하다.
#include <l;iostream>
using namespace std;
int& RefRetFuncOne(int &ref) {
	ref++;
	return ref;
}
int main() {
	int val1 = 1;
	int &val2 = RefRetFuncOne(val1);
	val1 += 1;
	val2 += 100;
	cout << "val1 : " << val1 << endl;
	cout << "val2 : " << val2 << endl;
	return 0;
}
결과
val1와 val2가 같은 값으로 출력되는 이유는 참조형으로 반환된 값을 참조자에 저장했기 때문이다.
① int val1 = 1;
② RefRetFuncOne(val1); 호출
③ int &ref = val1;
⑤ int &val2 = RefRetFuncOne(val1);
(ref는 지역변수로, 함수의 반환으로 인해 소멸된다.)
⑥ val1 += 1;
val2 += 100;
두 변수 모두 같은 값을 가리키고 있으므로, 그 값은 동일하게 103이 된다.
하지만 반환형이 참조형이어도, 참조자로 받지 않으면 결과가 달라진다.
#include <iostream>
using namespace std;
int& RefRetFuncOne(int &ref) {
	ref++;
	return ref;
}
int main() {
	int val1 = 1;
	int val2 = RefRetFuncOne(val1);
	val1 += 1;
	val2 += 100;
	cout << "val1 : " << val1 << endl;
	cout << "val2 : " << val2 << endl;
	return 0;
}
int val2 = RefRetFuncOne(val1);
참조자로 받지 않으면, num2는 별도의 다른 변수가 된다.
따라서 위와 같은 결과가 나오지 않는다.
결과
※ 주의
1. 지역변수를 참조형으로 반환하는 경우
지역변수를 참조형으로 반환, 참조자로 받게 되는 경우 문제가 있다.
위 예제에서 본 것과 같이, 지역변수는 함수가 반환되면 소멸된다.
따라서 참조자로 받게 되는 경우, 찌꺼기의 형태로 남아있는 데이터를 참조하게 되어 이상한 출력 결과가 나올 수 있다.
#include <iostream>
using namespace std;
int& RefRetFuncOne(int n) {
	int num = 10;
	num += n;
	return num;
}
int main() {
	int &val1 = RefRetFuncOne(10);
	cout << "val1 : " << val1 << endl;
	return 0;
}
결과
2. const 참조자 사용
const 선언으로 변수를 상수화한 후, 참조자를 통해 값을 변경하는 작업은 불가능하다.
(X)
const int num = 20; int &ref = num; ref += 10;
상수화된 변수에 대한 참조자 선언은 다음과 같이 해야 한다.
(O)
const int num = 20; const int &ref = num;
(O)
C++에서는 const 참조자를 이용해서 상수를 참조할 때 임시변수를 만든다.
그리고 이 장소에 상수 30을 저장하고, 참조자가 이를 참조하게끔 한다.
const int &ref = 30;
따라서 함수 내 매개변수를 const 상수화 시키는 것도 가능하다.
값이 변하면 안되는 매개변수에 const를 선언하면 실수로 발생하는 버그를 줄일 수 있다.
int Adder(const int &num1, const int &num2) {
	return num1 + num2;
}
'C++' 카테고리의 다른 글
| [C++] 구조체 (0) | 2019.03.08 | 
|---|---|
| [C++] new & delete (0) | 2019.03.08 | 
| [C++] 참조자(Reference) (0) | 2019.03.05 | 
| [C++] 기본 자료형 (0) | 2019.03.05 | 
| [C++] 인라인(inline) 함수 (0) | 2019.03.04 |