C++/카루의 C++ 강좌

[카루의 C++ 강좌] 2-5. 참조형 변수 I

카루-R 2020. 3. 22. 11:41
반응형

참조형 변수는 변수에 다른 이름을 붙이는 거라고 볼 수 있습니다.

#include <iostream>

int main()
{
    int original{}; // 기본값 0으로 초기화
    int copy{original};

    copy++;

    std::cout << "original: " << original << std::endl;  // 0이 출력됨
    std::cout << "copy: " << copy << std::endl;          // 1이 출력됨
    return 0;
}

출력 결과는 주석으로 설명해놓았습니다. 우리가 배운 초기화 방법중에 '복사' 초기화가 있었죠?

그런데 위에서 copy는 original을 복사했지만, 각각은 다른 변수이기 때문에 영향을 받지 않습니다.

복사를 하지 않고 참조를 사용하면 어떨까요?

int original{}; // 기본값 0으로 초기화
int &ref{original};

ref++;

std::cout << "original: " << original << std::endl; // 1이 출력
std::cout << "ref: " << ref << std::endl;           // 1이 출력

둘 다 1이 출력됩니다. 참조형 변수를 선언하는 방법은 다음과 같습니다.

Type &ref_var{other};

여기서 Type은 자료형을, ref_var은 참조형 변수의 이름을, other은 다른 변수를 뜻합니다.

즉, 복사 생성과 모양은 같지만 변수의 이름 앞에 &이 붙으면 '참조자'가 됩니다.

참조자는 레퍼런스라고도 부르며, &을 하나만 쓰는 경우엔 l-value 레퍼런스라는 이름을 갖습니다. &&이렇게 두 개가 붙으면 r-value레퍼런스라고 하는데, 이는 나중에 다루겠습니다.

&은 위치가 딱딱 정해진 건 아니고, 자료형과 변수의 사이에만 있으면 됩니다. 띄어쓰기는 영향을 받지 않습니다.

다음 세 문장 모두 올바른 문장입니다.

int&ref{original};
int& ref{original};
int & ref{original};

하지만 일반적으로는 변수 이름 앞에 붙여씁니다. 자료형 뒤에 붙일 경우 자칫 int& 형이라는 새로운 자료형 처럼 착각할 수가 있죠. 아무튼, 참조자는 선언과 동시에 반드시 초기화를 해야 합니다. 초기화는 등호를 사용해도 되지만, 우리는 중괄호로 통일하기로 약속했습니다. 그리고 일단 '참조' 형 변수기 때문에, 참조할 대상은 반드시 변수가 되어야 합니다. 왜냐하면 참조는 원본을 참조하여 값을 바꿀 수도 있는데, 상수는 값을 바꿀 수 없으므로 참조가 불가능합니다.

다만 상수는 변하지 않는 값이니, '상수형 참조'로 선언하면 가능하긴 합니다.

int &ref1{100};       // 에러! 상수는 참조할 수 없음
const int &ref2{500}; // 상수를 참조했지만, const로 선언했으니 괜찮음
auto &ref3{var};      // var을 선언했다면, var의 자료형에 맞춰서 참조로 선언됨

int &&r_value{200 + 30}; // r-value 참조는 이 경우를 위해 존재합니다.

조금 헷갈리시죠? 일단 하나만 기억하세요.

"참조자는 변수에 다른 이름을 붙이는 것이다!"라고요.

다음 예제를 살펴보겠습니다.

#include <iostream>

int static_var{20};
int main()
{
    int &refvar{static_var};
    refvar += 4;

    std::cout << static_var;      // 24가 출력
    return 0;
}

분명히 main() 함수 안의 refvar을 변경했음에도 불구하고 전역 인스턴스인 static_var이 영향을 받습니다. refvar이 static_var의 참조이기 때문입니다. 쉽게 생각하면 static_var에 refvar이라는 이름이 하나 더 붙은거죠. 이 코드에 한해서 둘은 완벽히 같다고 봐도 됩니다.


지금 당장은 참조자를 쓸 일이 많지 않을 겁니다. 변수에 다른 이름을 붙일 필요가 크게 느껴지지 않기 때문이죠.

이 참조자는 클래스와 사용자 정의 함수에서 크게 빛을 발합니다. 오늘 배운 건 많이 어렵지 않으니 꼭 기억하시길 바랍니다.

반응형