* 레퍼런스(Reference) (== 참조자) *
의미 : 어떤 다른 변수의 참고, 즉 다른 이름, '별명' 
         이미 존재하는 변수에 할당된 메모리 공간을 접근할 수 있는 또 다른 이름.

 

형태 : int &p ===> int형 레퍼런스 p

1
2
3
4
5
6
7
8
9
10
11
#include <iostream>
 
int main(){
    int number =2
    int &= number;  //number를 참조하는 레퍼런스 p 
    p = 5;            //p의 number참조로 number의 값이 5로 변경됨
    
    int &ref;  // 이런 문장은 존재 불가능! 
               // 존재하지 않는 것의 별명을 지을 필요는 없기 때문
    return 0;
}
http://colorscripter.com/info#e" target="_blank" style="color:#4f4f4ftext-decoration:none">Colored by Color Scripter


number의 값이 2 -> 5 로 변경


!! 레퍼런스(참조자)의 가장 중요한 특성 !! "반드시 정의 시 초기화" 되어야 함 !! 

!! 포인터(pointer)와 참조자(reference)의 차이 !!

  포인터 ==> 메모리 값(주소)을 보관하는 "변수"

  참조자 ==> 컴파일 시, 가리키는 변수의 주소값으로 치환되는 것.   

  1. NULL 값의 허용 여부
    포인터 ==> NULL 값 허용.
    참조자 ==> NULL 값이 될 수 없음.
  
    포인터의 경우 선언 시, NULL 값으로 초기화하지 않고 사용하면 에러가 나는 경우 발생.
    또한 잘못된 참조로 인해, 오류가 발생하기도 함.

    위의 오류를 방지하기 위해 참조자를 사용하면 좋음.
    NULL 값의 허용 여부에 따라, 허용하는 경우 NULL 여부를 체크하는 과정이 있어야 오류를 검사할 수 있음.
    허용하지 않는 경우, NULL 여부 체크를 생략해도 됨.

  2. 참조 대상 할당 및 접근
    포인터  ==>  참조 대상에 대해 &연산을 통해 주소값을 포인터에 할당
    참조자  ==>  참조 대상을 그대로 할당, 선언과 동시에 초기화를 하지 않으면 컴파일 오류 발생!

  3. 참조 대상 변경 가능 여부
    포인터 ==> 참조 대상을 언제든지 변경 가능
    참조자 ==> 참조 대상을 변경할 수 없음. "초기화 과정에서만 할당 가능"
                   재할당하는 경우에도 컴파일 에러 발생

1
2
3
4
5
6
7
8
9
10
#include <iostream>
 
int main(){
    int a = 10
    int &ref = a; 
    int b = 3
    ref = b; 
 
    return 0;
}

  참조자 ref는 a를 참조하고
  ref = b; 는 참조자 ref가 b를 참조하는 것이 아니라 b의 값 3이 a에 대입된다.
  즉, a=3;
---------------------------------------------------------------------------------------

% 참조자는 리터럴 상수를 참조할 수 없다. % 
상수를 참조하기 위해서는
const int &ref = 4;
와 같은 형태로 "const" 키워드를 사용하여 참조

% 참조자의 배열은 "illegal" % 
  참조자는 이미 메모리 상에 존재하는 변수의 주소값에 대한 또 다른 이름으로
  별도의 메모리 공간을 차지하지 않는 것인데,
  메모리 공간을 차지하지 않는 것의 포인터는 모순.
  배열의 첫번째 이름은 포인터.

% 배열의 레퍼런스는 가능하다. ( 잘 사용하지 않음 ) % 
  형태 : int (&ref)[3] ;
  배열의 크기를 명확히 명시해 주어야 한다.
  포인터를 사용하면 int *p 하나로 사용가능하여 배열의 경우 "포인터"를 권장.

% 레퍼런스를 리턴하는 함수 %

1
2
3
4
5
6
7
8
#include <iostream>
 
int fn1(int &a) { return a; } 
 
int main() { 
  int x = 1
  std::cout << fn1(x)++ << std::endl
http://colorscripter.com/info#e" target="_blank" style="color:#4f4f4ftext-decoration:none">Colored by Color Scripter


위의 코드는 복사된 x값, 1이 리턴되어 수정이 불가능. 따라서 fn1(x)++ 불가.

1
2
3
4
5
6
7
8
9
#include <iostream>
 
int &fn2(int &a) { return a; } 
 
int main() { 
    int x = 1
    std::cout << fn2(x)++ << std::endl
    std::cout << "x :: " << x << std::endl
http://colorscripter.com/info#e" target="_blank" style="color:#4f4f4ftext-decoration:none">Colored by Color Scripter


위의 코드는 fn2에서 x의 참조자로 a를 지정하고, 별명인 a를 반환하므로 fn2(x)++ 가능.
------------------------------------------------------------------------------------

 

결과적으로 보다 안정성있는 프로그램을 작성하기 위해 참조자를 사용함.
참조자로 가능한 경우 왠만하면 참조자 사용, 어쩔 수 없는 경우 포인터 사용.

반응형

'C++' 카테고리의 다른 글

클래스(Class) (2) - 접근 지정자  (0) 2020.03.31
클래스(Class) (1) - 객체, 클래스 설명  (0) 2020.03.31
메모리 할당 (new,delete)  (0) 2020.01.26
이름 공간(Name Space)  (0) 2020.01.23

+ Recent posts