[C++] 참조자 (reference) 의 정의, 사용법 및 주의 사항

2023. 3. 28. 22:11·개발/C, C++
반응형

C++에서 활용되는 참조자 (reference)에 대해서 알아보도록 하겠다.

 

[C++] 참조자 (reference)의 정의 및 사용법

 

참조자 (reference)의 정의

C언어에서 변수를 가리키는 것으로 포인터를 사용한다.

예를 들어 아래와 같이 포인터 변수 p를 선언하고 변수 a를 가리키게 하고 가리키는 값인 *p를 출력하면 3이 출력된다.

int main(void) {
   int *p;
   int a = 3;
   p = &a;
   std::cout << *p << std::endl;
}

참조자는 포인터 변수와 비슷하게, C++ 에서 활용되는 변수를 가리키는 방법이다.

아래처럼 int& ref = value; 와 같이 ref라는 참조자가 value를 가리키도록 한다. ref는 value를 가리키는 별명 같은 것이다.

int value;
int& ref = value;

 

 

 

참조자 (reference)의 사용법

 

내가 가리키고 싶은 변수가 있고, 그 변수의 별명을 ref 라고 지정하고 ref를 출력하는 코드이다. 포인터와는 다르게 * 같은 별도의 기호를 붙임이 않고도 ref 자체만으로도 a처럼 그대로 출력하면 된다. 즉 ref 가 a 인 셈이다. 이게 가능한 이유는 참조자는 단순히 별명 같은 것이고, 새로운 메모리를 할당하는 것이 아니라 컴파일 시에 ref와 a가 동일하게 취급되기 때문이다.

int main(void) {
   int a = 3;
   int& ref = a;
   std::cout << ref << std::endl;
}

 

아래는 함수의 인자로 전달하는 경우의 예시이다. 포인터를 사용하는 경우와 비교하기 위해 두 가지 함수를 만들어 보았다.

add_one_reference는 인자로 참조자를 받고 add_one_pointer는 인자로 포인터 변수를 받는다. 어차피 인자에는 * 혹은 & 이 붙어야 하는 것은 똑같지만 함수 내에서 값을 접근할 때 참조자는 그대로 사용하면 되지만 포인터는 * 를 붙여서 접근해야 한다. 또한 main 함수에서 호출할 때에 포인터는 변수 a에 &를 붙여서 주소값을 넘겨주어야 하지만 참조자의 경우는 그냥 넘겨주면 된다. 참조자가 훨씬 깔끔하고 직관적이다.

#include <iostream>

void add_one_reference(int& input) {
   input++;
}

void add_one_pointer(int* input) {
   *input = *input + 1;
}

int main(void) {
   int a = 3;

   add_one_pointer(&a);
   std::cout << a << std::endl;

   add_one_reference(a);
   std::cout << a << std::endl;
}

 

 

참조자(reference) 사용 시 주의 사항

1. 참조자는 새로운 변수가 아니라 별명에 불과하다는 사실을 제일 먼저 인지해야 한다.

2. 참조자는 선언과 동시에 초기화가 되어야 한다. 1번에서 말했다 시피 별명에 불과한데, 별명의 주체가 없는 null 별명은 존재할 수 없는 것이다.

3. 참조자는 한 번 지정이 되면 참조하는 대상을 변경할 수 없다. 포인터 변수처럼 이렇게 저렇게 바꿔가면서 사용하는 용도가 아니다. 참조자에 다른 변수를 지정한다면 그것은 원래 가리키던 값의 변수를 변경하는 것이 된다.

int main(void) {
   int a = 3;
   int& ref = a;
   std::cout << ref << std::endl; // ref 츌력결과 : 3
   
   int b = 5; // 새로운 b 등장
   ref = b; // ref 를 b를 가리키도록 함?? 
   // 아니다. ref는 a와 같으므로 a = b 가 되어 a 값을 5로 변경한다.
   
   std::cout << ref << std::endl; // ref 출력결과 : 5
   // b를 가리키도록 했으니 5가 출력되었나?? 아니다. ref인 a가 위에서 5로 변경되었기 때문이다.
   
   std::cout << a << std::endl; // a 출력결과 : 5
}

4. Call by value와 잘 구분해서 사용해야 하면 헷갈리면 안된다. 포인터를 사용하면 Call by value와 Call by reference 가 얼핏 봐도 구분이 되지만 참조자를 사용하면 실수할 수도 있으니 조심해야 한다.

 

 

결론

참조자는 간단한 듯 하면서도 헷갈리는 부분이 있다. 포인터와의 차이점을 명확하게 이해하고 넘어가는게 좋은 것 같다. 코드의 간결성 때문에 C++에서 실제로 굉장히 많이 사용되고 있기 때문이다.

저작자표시 비영리 변경금지 (새창열림)

'개발 > C, C++' 카테고리의 다른 글

[C++] class 생성자에서 explicit 키워드의 의미  (0) 2023.09.05
[C++] STL 컨테이너 Set과 Map 활용법과 차이점  (0) 2023.09.02
[C++] STL 컨테이너 Vector 의 용도와 특징, 사용 예제  (0) 2023.09.01
[C++] 생성자에서 virtual 가상 함수 호출하는 경우의 문제  (0) 2023.08.11
[C++] 복사 생성자(Copy Constructor) 의 이해 및 활용  (1) 2023.07.27
'개발/C, C++' 카테고리의 다른 글
  • [C++] STL 컨테이너 Set과 Map 활용법과 차이점
  • [C++] STL 컨테이너 Vector 의 용도와 특징, 사용 예제
  • [C++] 생성자에서 virtual 가상 함수 호출하는 경우의 문제
  • [C++] 복사 생성자(Copy Constructor) 의 이해 및 활용
growing-dev
growing-dev
S/W 개발 관련 내용들과 취미나 육아, 맛집 등 관심 있는 내용을 공유하는 블로그입니다.
    반응형
  • growing-dev
    성장하는 개발자 블로그
    growing-dev
  • 전체
    오늘
    어제
    • 분류 전체보기 N
      • 개발
        • 개발 공통
        • 개발 환경
        • Git
        • 자료구조, 알고리즘
        • C, C++
        • Python
        • DevOps
        • CMake
      • 공부
        • 영어
        • 경제
      • 취미, 육아 N
        • 육아
      • 생활정보
  • 블로그 메뉴

    • 홈
  • 링크

    • growing-dev GitHub
  • 공지사항

    • [블로그 시작] 성장하는 개발자 스토리입니다.
  • 인기 글

  • 태그

    OPIC
    WSL
    C++
    앨리웨이
    티스토리챌린지
    키즈카페
    소프티어
    오픽
    CMake
    프로그래머스
    필스너
    Python
    하이볼
    dfs
    Clang
    VS Code
    git
    오블완
    TDD
    생산성
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.1
growing-dev
[C++] 참조자 (reference) 의 정의, 사용법 및 주의 사항
상단으로

티스토리툴바