Computer Science/C++

[C++] 참조자(레퍼런스)의 도입 - 씹어먹는 C++ 2강

토마토. 2021. 7. 17. 15:11

<참조자의 도입>

"뉴페이스" 참조자!

C에서 변수/상수를 가리키려면,

포인터를 사용해야 한다.

C++에서는 변수/상수를 가리킬 때

포인터뿐만 아니라, '참조자'를 사용할 수 있다.

 

기본 문법

int a = 3;

int &refer = a;

#include <iostream>

int main() {
	int number = 3;
	int& save = number;
	std::cout << "save" << save << std::endl;
	std::cout << "number" << number << std::endl;
	return 0;
}

 

특징

1. 정의 시에 참조하는 변수를 명시해야 함

2. 레퍼런스를 바꿀 수 없다.

3. 메모리상에 존재하지 않을 수 있다. 

 

<함수의 인자로 레퍼런스 받기>

#include <iostream>

int change_val(int& p) {
	p = 10;
	return 0;
}

int main() {
	int number = 3;
	int& refer = number;
	change_val(refer);

	std::cout << number << std::endl;
	return 0;
}

포인터와 달리,

위 함수에 원래 변수 number를 대입할 때

(X) change_val(&number);

(O) change_val(number);

 

<여러가지 참조자 예시들>

ex1

reference를 정의하고 나면,

이름을 새로 붙여준 것과 같이

상태가 동기화된다.

de <iostream>

int main() {
	int x;
	int& y = x;
	int& z = y;

	x = 1;
	std::cout << "x : " << x << std::endl;
	std::cout << "y : " << y << std::endl;
	std::cout << "z : " << z << std::endl;

	y = 2;
	std::cout << "x : " << x << std::endl;
	std::cout << "y : " << y << std::endl;
	std::cout << "z : " << z << std::endl;
}

 

<상수에 대한 참조자>

상수 참조자로 선언하면, 리터럴도 참조할 수 있다.

** literal **

소스 코드 상에서 고정된 값

문자열에서는 "" 안의 값

 

<레퍼런스의 배열과 배열의 레퍼런스>

레퍼런스의 배열

int a, b;int &arr[2] = {a, b};-> 불가능레퍼런스는 메모리상에서 공간을 차지하지 않기 때문에*(arr+1)과 같이 메모리를 참색하여 a를 찾을 수 없음.

 

배열의 레퍼런스

#include <iostream>

int main() {
	int arr[3] = { 1,2,3 };
	int(&ref)[3] = arr;

	ref[0] = 10;
	ref[1] = 20;
	ref[2] = 30;

	std::cout << arr[0] << arr[1] << arr[2] << std::endl;

	return 0;
}

<레퍼런스를 리턴하는 함수>

case 1. pass by value

a 값이 main 함수의 int b로 복사된다. 

a는 메모리에서 사라진다.

#include <iostream>

int &function() {
	int a = 2;
	return a;
}

int main() {

	int b = function();
	std::cout << b << std::endl;
	return 0;
}

case 2. 외부 변수 레퍼런스를 리턴

#include <iostream>

int &function(int &a) {
	a = 5;
	return a;
}

int main() {
	int b = 2;
	int c = function(b);
	std::cout << c << std::endl;
	return 0;
}

case 3. 참조자 아닌 값을 리턴하는 함수를 참조자로 받기

상수 레퍼런스로 리턴값을 받으면, 

리턴값의 생명이 연장된다.

 

<연습문제>

Q. 레퍼런스가 메모리상에 반드시 존재해야 하는 경우는? 

참조하는 변수가 같은 함수 내에 있는 경우

 

Q. 레퍼런스가 메모리상에 존재할 필요가 없는 경우는?

함수가 끝나고 

runtime이 다음 영역으로 간 경우