본문 바로가기
개념

[C++] 참조자 개념 (2) const 참조자와 참조형을 반환하는 함수

by 부먹짱 2022. 9. 30.
반응형

 

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) :  해제된 메모리를 참조하는 참조자

 

반응형

댓글