반응형

1. 참조자

참조자는 C에서 C++로 넘어오면서 생긴 새로운 개념이다.

#include<iostream>

int main()
{
	int num = 15;
	int& ref = num;

	std::cout << "num: " << num << std::endl;
	std::cout << "ref: " << ref << std::endl;
	
	ref += 5;

	std::cout << "num: " << num << std::endl;
	std::cout << "ref: " << ref << std::endl;

	return 0;
}

그림 1. 실행결과.

참조자는 변수의 다른 이름, 즉 별명과 같은 역할을 수행한다.

따라서 한번 할당되고 나면 ref와 num은 코드 내에서 같은 의미를 지닌다.

 

그런데, 별명을 붙이는 것은 좋으나 이를 어디에 유용하게 사용할 수 있을까?

참조자를 함수의 매개변수로 넘기는 것은 call-by-reference의 효과를 갖는다.

#include<iostream>

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

int main()
{
	int num1 = 15;
	int num2 = 20;

	std::cout << "호출 전: " << num1 << " , " << num2 << std::endl;

	swap(num1, num2);

	std::cout << "호출 후: " << num1 << " , " << num2 << std::endl;

	return 0;
}

그림 2. 실행결과.

함수를 보면 매개변수로 참조자 변수를 받고 있다.

함수 내부에서는 일반 변수처럼 사용되고, 인자의 값에 직접적으로 접근하여 바꾸는 것을 보여주고 있다.


2. 포인터와 참조자의 차이점

참조자를 전부 포인터로 교체해도 동일한 효과를 지닌다.

둘은 어떤 차이가 있을까?

참조자 포인터
선언과 동시에 초기화 되어야함. 선언만 해두고 나중에 값을 넣을 수 있음.
초기화 되고나면 값을 바꿀 수 없음. 값을 바꿀수 있음.
null값을 넣을 수 없음.  null값을 넣을 수 있음

가장 근본적인 차이점은 위와 같다.

항상 초기화되어야 하고, 값을 변경할 수 없기 때문에 포인터보다 안전하다.

 

C++ FAQ에서는 다음과 같이 언급되어 있다.

Use references when you can, and pointers when you have to.
사용할 수 있다면 참조자를 쓰고, 어쩔 수 없을 경우에만 포인터를 써라.
- https://isocpp.org/wiki/faq/references#refs-vs-ptrs 

그만큼 포인터보다 참조자를 쓰는 것이 안전하다는 의미를 나타내는 듯하다.


3. 참조자와 매개변수

참조자는 매개변수로 사용될 때 성능의 이득을 볼 수 있다.

#include<iostream>

int Sum1ToN(int n)
{
	std::cout << "variable address : " << &n << std::endl;
	return (n * (n + 1)) / 2;
}

int Sum1ToN_ref(int &n)
{
	std::cout << "ref address : " << &n << std::endl;
	return (n * (n + 1)) / 2;
}

int main()
{
	int n;
	std::cin >> n;
	std::cout << "n address : " << &n << std::endl;
	Sum1ToN(n);
	Sum1ToN_ref(n);

	return 0;
}

그림 3. 실행결과.

참조자를 매개변수로 사용한 경우와 그렇지 않은 경우의 결과이다.

참조자를 사용하지 않았을 경우는 인자와 주소 값이 다르고,

참조자를 사용했을 경우에는 주소 값이 동일하다.

 

따라서 인자의 크기가 커서 복사에 많은 비용이 사용될 경우,

참조자를 사용하면 성능에서 이득을 볼 수 있다.


읽을거리.

C언어에 Call by Reference는 없다.

- C에는 근본적으로 Call by Value만 존재하므로 Call by Address 혹은 Call by Reference의 흉내내기 정도로

불러야 한다는 내용이다. 말장난처럼 들릴 수도 있지만, 정확하게 짚고 넘어가면

Call by Reference가 아니므로 C에서 Call by Reference가 없다는 것을 명심하자.

반응형

'개념정리 > C++' 카테고리의 다른 글

7. 복사 생성자  (0) 2021.04.21
6. Friend 키워드  (0) 2021.04.21
4. 동적할당과 소멸자  (0) 2021.04.19
3. 클래스  (0) 2021.04.18
2. Namespace  (0) 2021.04.17

+ Recent posts