[디딤돌 C++] 9. 레퍼런스 변수

C++언어에서 변수 선언문에서 &를 사용하는 참조 변수 선언을 제공하고 있습니다. 참조 변수는 별도의 메모리를 할당하지 않고 변수 선언문에서 초기화에 사용한 변수의 메모리를 참조하여 사용합니다.

#include <iostream>
using namespace std;
int main()
{
    int i =0;
    int &r = i; //r은 i변수를 참조

    r = 9; //i=9;와 같은 결과(r 변수는 i변수를 참조)
    cout<<"i:"<<i<<endl;
    return 0;
}

▷ 실행 결과

i:9

이러한 이유로 레퍼런스 변수는 선언과 함께 초기화를 해 주어야 합니다. 그리고 반드시 초기화에 사용하는 우항은 l-value(대입 연산자의 좌항에 올 수 있는 표현)여야 합니다. 참조 변수 선언문에 초기화를 하지 않거나 상수로 초기값을 설정하면 컴파일 오류가 발생해요.

//참조 변수 선언 오류
#include <iostream>
using namespace std;

int main()
{
    int &r1; //참조 변수는 선언부에서 초기화는 필수
    int &r2 = 3; //참조 변수에 초기값은 상수 올 수 없음(lvalue여야 함)

    return 0;
}
참조 변수 선언 오류

참조 변수는 메모리를 별도로 하지 않는 점을 제외하면 일반 변수와 사용 방법이 같습니다. 그리고 함수의 반환 형식을 참조 변수로 지정하고 지역 변수를 반환하지 마세요. 반환한 변수를 참조하게 반환하였을 때 이미 지역 변수는 무효화 상태여서 버그를 발생할 수 있어요.

다음의 코드는 s에서 e 사이에 정수의 합계를 구하는 함수를 호출하여 사용한 예제 코드예요. 반환 형식은 int &로 정의하였고 지역 변수 sum을 반환하고 있어요. 컴파일은 가능하지만 경고 메시지가 나오고 실제 수행해 보면 버그가 있음을 알 수 있어요.

예제에서는 1에서 100사이의 합계를 r1 변수가 참조하고 1에서 10 사이의 합계는 r2 변수가 참조하고 있어요. 하지만 이미 반환한 sum은 피 호출 함수의 지역 변수라 메모리가 무효화 상태죠. 출력 결과를 보면 둘 다 55를 반환하고 있음을 알 수 있어요.

//참조 반환
#include <iostream>
using namespace std;

int &CalSum(int s,int e);
int main()
{
    int &r1 = CalSum(1,100); //참조 변수는 선언부에서 초기화는 필수
    int &r2 = CalSum(1,10);
    cout<<"r1:"<<r1<<", r2:"<<r2<<endl;

    return 0;
}

int &CalSum(int s,int e)
{
    int sum = 0;
    for(  ; s<=e; s++)
    {
        sum += s;
    }
    return sum;
}

▷실행 결과

r1:55, r2:55
지역 변수의 주소 반환 경고

마지막으로 함수 중복 정의할 때 입력 매개 변수가 참조와 값만 차이가 있으면 호출할 때 변수를 전달했을 때 어느 것을 호출하는지 모호해서 참조 입력 매개 변수로 정의한 함수를 부를 수가 없습니다. 따라서 함수 중복 정의할 때는 참조와 값만 차이가 있게 작성하지 마세요.

//참조와 값만 차이가 있는 함수 중복 정의
#include <iostream>
using namespace std;

int Add(int &r1, int &r2);
int Add(int i,int j);
int main()
{
    int re = Add(2,3);
    cout<<"re:"<<re<<endl;
    int a=2,b=3;
    re = Add(a,b);
    cout<<"re:"<<re<<endl;
    return 0;
}
int Add(int &r1, int &r2)
{    
    return r1+r2;
}
int Add(int i,int j)
{ 
    return i+j;
}
오버로드된 함수에 대한 호출이 모호합니다.