Software Development/C, C++

[C++] 참조자(Reference)의 이해

huiyu 2018. 12. 9. 10:49

- 변수 : 변수는 할당된 메모리 공간에 붙여진 이름이다. 그리고 그 이름을 통해서 해당 메모리 공간에 접근 가능하다.


할당된 하나의 메모리 공간에 둘 이상의 이름을 부여할 수는 없을까?

  -> int &num2 = num1;

* 위 코드는 num1이라는 이름이 붙어있는 메모리 공간에 num2라는 이름이 하나 더 붙게 된다.


int *ptr = &num1;        //   변수 num1의 주소 값을 반환해서 포인터 ptr에 저장
int &num2 = num,1;     //    변수 num1에 대한 참조자 num2를 선언

-> num2는 num1에 대한 '참조자'가 되며, num1이라는 메모리 공간에 num2라는 이름이 하나 더 붙은 꼴이 된다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <iostream>
using namespace std;
 
int main(void)
{
  int num1 = 1020;
  int &num2 = num1;
 
  num2 = 3047;
  cout<<"VAL:  "<<num1<<endl;
  cout<<"REF:  "<<num2<<endl;
 
  cout<<"VAL:  "<<&num1<<endl;
  cout<<"REF:  "<<&num2<<endl;
  return 0;
}
cs

 //실행결과

1
2
3
4
VAL:  3047
REF:  3047
VAL:  0012FF60
REF:  0012FF60
cs

-> 변수와 참조자는 선언의 방식에 있어서 확실한 차이를 보인다.
  참조자는 변수를 대상으로만 선언이 가능하기 때문이다. 하지만 일단 선언이 되고 나면, 변수와 차이가 없다.
  위 예제에서 보이듯이 & 연산자를 이용해서 주소 값을 반환 받을 수도 있고,
  함수 내에서 선언된 지역적(local) 참조자는 지역 변수와 마찬가지로 함수를 빠져나가면 소멸된다.


* 참조자는 변수에 별칭(별명)을 하나 붙여주는 것이다.

* 참조자의 수에는 제한이 없다.
   int num1   = 2759;
   int &num2 = num1;
   int &num3 = num1;
   int &num4 = num1;

* 참조자를 대상으로도 참조자를 선언할 수 있다.
  int num1   = 2759
  int &num2 = num1;
  int &num3 = num2;
  int &num4 = num3;

* 참조자의 선언 가능 범위

  - 참조자는 변수에 대해서만 선언이 가능하고, 선언됨과 동시에 누군가를 참조해야만 한다. 즉 다음은 유효하지 않다.
   변수에 또 다른 이름을 붙이는 것이기 때문에 상수를 대상으로 참조자를 선언할 수 없다.
    int &ref = 20;   (x)


  - 다음과 같이 미리 참조자를 선언했다가, 후에 누군가를 참조하는 것은 불가능하며, 참조의 대상을 바꾸는 것도 불가능
    int &ref;       (x)

 - 다음과 같이 참조자를 선언하면서 NULL로 초기화하는 것도 불가능하다.
    int *ref = NULL;

* 배열의 요소도 참조자 선언이 가능하다.

1
2
3
4
5
6
7
8
9
10
11
12
#include <iostream>
using namespace std;
int main(void)
{
  int arr[3= {135};
  int &ref1 = arr[0];
  int &ref2 = arr[1];
  int &ref3 = arr[2];
  cout<<ref1<<endl;
  cout<<ref2<<endl;
  cout<<ref3<<endl;
}
cs

* 포인터 변수도 변수이기 때문에 참조자 선언이 가능하다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <iostream>
using namespace std;
int main(void)
{
  int num = 12;
  int *ptr = &num;
  int  **dptr = &ptr;
 
  int &ref = num;
  int *(&pref) = ptr;
  int **(&dpref) = dptr;
 
  cout<<ref<<endl;
  cout<<*pref<<endl;
  cout<<**dpref<<<endl;
 
  return 0;
}
 
cs


[참고자료]
- 윤성우의 열혈 C++ 프로그래밍 02-4 참조자(Reference)의 이해


728x90