본문 바로가기
C++

[C++]Reference 레퍼런스

by Junk_Seo 2018. 1. 24.
반응형

Reference 레퍼런스

C++ 에는 레퍼런스라는 형식이 존재합니다. 

사용법은 다음과 같습니다.

int nData1 = 0;
int& nData2 = nData1;

& 키워드를 사용하며 레퍼런스 변수는 생성과 동시에 반드시 초기화를 해 주어야 합니다. 

반드시 자료형에 맞는 변수로 초기화를 해주어야 하며 상수로는 초기화가 불가능합니다.

 

단 const 키워드를 사용하면 상수로 초기화 가능합니다.

const int& nData2 = nData1; 

 

레퍼런스 변수는 이름이 붙여진 변수의 메모리에 다른 이름을 부여하는 형태로 메모리를 잡지 않는다는 이점이 있습니다.

그리고 C++에서 레퍼런스는 한 번 붙으면 없어지지 않기 때문에 사용 범위는 거의 함수 인자용으로 사용됩니다.

함수의 인자로 레퍼런스를 사용하면 인자 전달 과정에서 메모리를 잡거나 값을 복사하는 과정이 없어지기 때문에 일반 변수나 포인터 변수를 사용하는 것보다는 이점이 생기게 됩니다. 

 

C++에서 레퍼런스가 아닌 일반 변수나 포인터를 사용하여 인자로 받으면 인자로 받는 과정에서 임시 변수를 생성하여 메모리를 잡고 그 메모리에 인자로 들어오는 값을 복사하는 과정이 있습니다. 하지만 레퍼런스의 경우 메모리를 잡지 않고 인자로 들어온 변수의 메모리에 접근할 수 있게 됩니다.

 

예를 들면

void printData(const int* pData);

int main()
{
	int nData = 100;
	printData(&nData);
    return 0;
}

void printData(const int * pData) {
	printf("%d \n", *pData);
}

다음과 같이 printData라는 함수는 인자로 포인터를 받아 그 포인터 변수가 가리키는 곳의 값을 출력합니다.

이때 인자를 받는 과정에서 메모리에 int* 의 크기인 4byte를 잡고 거기에 인자로 들어오는 값을 복사한 뒤에 그 값을 사용하게 됩니다.

즉, 메모리를 잡고 값을 복사하는 과정이 보이진 않지만 있다는 거죠.

 

하지만 레퍼런스를 인자로 사용하면 그 내용이 달라지게 됩니다.

void printData(const int& nInput);

int main()
{
	int nData = 100;
	printData(nData);
    return 0;
}

void printData(const int& nInput) {
	printf("%d \n", nInput);
}

이렇게 인자로 레퍼런스를 사용하면 함수의 인자로 들어오는 값의 메모리에 다른 이름을 붙이고 그 메모리의 값을 직접 사용하게 되어 메모리를 잡고 값을 복사하는 과정이 없어집니다.

 

하지만 배열을 인자로 받는 경우에는 레퍼런스가 아닌 포인터를 사용합니다.

void printData(const int (&arData)[4]);

int main()
{
	int arData[4] = {};
	printData(arData);
    return 0;
}

void printData(const int(&arData)[4]) {
	for (int i = 0; i < 4; i++) {
		printf("%d \n", arData[i]);
	}
}

레퍼런스로 배열을 함수의 인자로 받는 경우 위 코드와 같은 형태를 취하는데 문제점음 배열의 길이가 정적으로 정해진다는 것이다. 

위 함수와 같이 인자를 설정한 경우 배열의 길이가 무조건 4인 형태만 인자로 받을 수 있기 때문에 배열을 인자로 받는 경우에는 레퍼런스가 아닌 포인터의 형태로 받습니다.

반응형