const 참조자
const int num = 1; // 상수화된 변수
int &ref = num; // Compile Error!
const int num = 1;
const int &ref = num; // 가능
일반 참조자는 상수화된 변수를 참조할 수 없다.
이는 상수화되었다면 어떠한 방법을 사용하든 값의 변경이 허용되지 않기 때문이다.
하지만 const 참조자는 상수화된 변수를 참조할 수 있다.
const 키워드를 붙이는 것은 참조자를 통한 값의 변경을 진행하지 않을 것이라는 의미이기 때문이다.
const int &ref = 1; // 리터럴 상수 참조 가능
프로그램 상 표현되는 숫자를 가르켜 리터럴 상수라고 한다.
리터럴 상수는 임시로 존재하는 값으로 다음 행으로 넘어가면 소멸한다.
이러한 상수를 const 참조자가 참조하는 것은 부자연스러운 일이다.
하지만 C++에서는 const 참조자를 이용해 상수를 참조할 때, 해당 상수에 대한 임시 변수를 만들어 const 참조자가 그 임시 변수를 참조하도록 한다.
결국 상수화된 변수를 참조하는 형태와 같은 것이다.
C++에서 임시 변수를 만들면서까지 이를 허용하는 이유는 아래와 같은 함수 때문이다.
int Sum(const int &num1, const int &num2)
{
return (num1 + num2);
}
void main()
{
Sum(1, 2); // 간단히 호출!
// 상수 참조를 허용하지 않으면....
int n1 = 1;
int n2 = 2;
Sum(n1, n2);
}
const 참조자의 상수 참조를 허용함으로써, 함수의 호출이 간단해졌다.
그렇지 않았다면 매번 변수를 생성하여 함수를 호출해야한다.
참조형을 반환하는 함수
int& RetrunRef(int & ref)
{
ref++;
return ref;
}
void main()
{
int num1 = 1;
int num2 = RetrunRef(num1); // 일반 변수로 저장
int &num3 = RetuunRef(num1); // 참조형으로 저장
num3 += 1;
cout << num1 << endl; // 4
cout << num2 << endl; // 2
cout << num3 << endl; // 4
}
함수의 반환형이 참조형인 경우, 반환 값을 두 가지 형태로 저장할 수 있다.
1. 일반 변수로 저장
이 경우는 반환한 참조형이 참조하는 변수와 완전히 별개의 변수로 사용된다.
(num1과 num2는 별개의 변수)
2. 참조형으로 저장
이 경우에는 참조형이 참조하는 변수를 참조하게 된다.
(num3은 num1을 참조)
함수 안 지역 변수의 참조형을 반환하면 어떻게 될까
int& ReturnRef()
{
int ref = 10;
return ref;
}
void main()
{
int &num = ReturnRef(); // 컴파일 경고
cout << num << endl; // 런타임 에러
}
이 경우, 컴파일 에러는 나지 않지만 함수 내 지역 변수는 소멸되어 찌꺼기 값이 출력된다.
이미 소멸된 메모리의 값을 참조하는 실수를 하지 않도록 주의가 필요하다.
* 댕글링 레퍼런스(Dangling Reference) : 해제된 메모리를 참조하는 참조자
'개념' 카테고리의 다른 글
[C#] 클래스의 메모리 할당 (Stack, Heap) (1) | 2022.09.20 |
---|---|
[개념] 메모리의 구조 (0) | 2022.09.20 |
[C++] 참조자 개념 (1) 참조자와 Call-by-reference (0) | 2022.09.20 |
[개념] 구조체 패딩 (Struct Padding) (1) | 2022.04.15 |
[개념] 빅 엔디안 & 리틀 엔디안 (Big-Endian & Little-Endian) (0) | 2022.03.28 |
댓글