본문 바로가기
C,C++/정보정리

[C/C++] Reference(참조)

by 마두식 2022. 10. 11.
반응형
Reference
  • 레퍼런스는 메모리 상에 존재하지 않을 수도 있다.

-  단순히 특정 범위 내(함수 등) 하나의 변수에 대한 레퍼런스를 만드는 경우 굳이 메모리 상에 존재할 필요가 없다.

-  레퍼런스가 쓰이는 자리를 모두 원래 변수로 대체할 수 있기 때문이다

 

 

  • 레퍼런스들의 배열, 레퍼런스의 레퍼런스, 레퍼런스의 포인터 등은 언어 차원에서 금지되어 있다.

-  레퍼런스의 레퍼런스는 원래 변수의 별명의 별명 이라는 말과 같다. 즉, 불필요하다.

-  레퍼런스는 특별한 경우가 아닌 이상 메모리 상에서 공간을 차지하지 않는다.

-  배열이나 포인터는 주소값을 반드시 포함하는 개념이기 때문에 레퍼런스가 메모리 상에서 공간을 차지하지 않는다는 것과 모순이다. 따라서 언어 차원에서 금지되어 있는 것이다.

-  별개로 배열의 레퍼런스는 가능하다. 포인터와는 다르게 배열의 레퍼런스의 경우 참조를 위해 반드시 배열의 크기를 명시해야 한다.

 

  • 레퍼런스가 메모리 공간을 차지하는 경우

-  함수의 매개변수로 레퍼런스를 사용할 경우, 레퍼런스는 메모리 공간을 차지한다.

-  상수 지시 레퍼런스(const T&)의 경우, 리터럴 값을 가리키기 위해 메모리 공간을 차지한다.

 

 

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

-  지역 변수의 레퍼런스를 리턴하게 될 경우 원본은 사라지고 참조자만 남게되는 '댕글링 레퍼런스'가 발생한다.

-  이런 경우 컴파일 에러가 아닌 런타임 에러가 발생하므로 레퍼런스를 리턴하는 함수에서 지역변수의 레퍼런스를 리턴하지 않도록 주의해야 한다.

-  함수 리턴값으로 레퍼런스를 사용해야 하는 경우는 연사자를 오버로딩 할 때이다.

 

 

  • 레퍼런스가 아닌 값을 리턴하는 함수를 레퍼런스로 받기

-  일반적으로 함수의 리턴 값은 해당 함수가 끝나면 소멸되는 것이 정상이다.

-  예외적으로 상수 지시 레퍼런스(const T&)로 리턴값을 받게 되면 해당 리턴값의 생명이 연장되어, 해당 상수 지시 레퍼런스가 사라질 때까지 남아있게 된다.

 

 

  • 레퍼런스의 사용법

-  엄청나게 큰 구조체를 함수의 인자로 넘기거나, 리턴값으로 받아올 때 값을 받아오게 되면 해당 구조체의 전체 복사가 발생해서 비용이 많이 든다.

-  이런 경우 포인터나 레퍼런스를 사용하면 참조하는 타입의 크기와 상관없이 딱 한 번의 주소값 복사로 전달이 끝나 매우 효율적이다.

-  단, 레퍼런스를 매개변수로 사용할 경우 상수 값이나, 수식을 인자로 넘겨줄 수 없다.

-  상수 지시 레퍼런스(const T&)라면 수식이나 상수 값 또한 인자로 받을 수는 있지만 그렇게 되면 해당 함수 내에서 인자로 넘어온 값을 변경할 수는 없다.

-  포인터에 대한 레퍼런스는 종종 사용된다.

-  이중 포인터를 레퍼런스로 사용할 경우 훨씬 깔끔하고 직관적으로 코드를 작성할 수 있기 때문이다.

-  함수 레퍼런스나 배열에 대한 레퍼런스는 크게 자주 사용되지는 않는다.

 

 

  • 레퍼런스 사용 시 주의사항

-  함수의 매개변수로 레퍼런스를 사용할 경우, 함수 호출에서 인자를 넘겨주는 형식이 값을 넘겨주는 방법과 똑같기 때문에, 다른 사람이 내 코드를 읽을 때 혼란을 줄 수도 있다.

-  따라서, 레퍼런스를 매개변수로 사용하는 함수 명에 Ref나 ByRef와 같은 접미를 붙여서 함수 형식을 쉽게 파악할 수 있도록 해주기도 한다.

-  포인터를 매개변수로 이용하면 배열처럼 주변 주소에 접근해서 다른 값들을 조작할 수 있지만, 레퍼런스의 경우 그러한 행동이 어려울 수 있다.

-  함수 내부에서 동적 할당을 할 때는 포인터를 쓰는 것이 더 낫다.

-  리턴 값으로 레퍼런스를 사용할 경우, 해제해야 할 포인터를 잃어버릴 수도 있기 때문이다.

=>  동적할당으로 값을 지정해준 포인터를 레퍼런스로 넘겨받고, 해당 레퍼런스를 반환한다면 그 함수를 호출할 때 사용한 변수의 타입에 따라 다르겠지만 상황에 따라서는 값만 전달받고 동적할당 한 포인터는 잃어버리는 경우가 생길 수도 있다.

 

 

  • 레퍼런스 내부 원리

-  레퍼런스는 컴파일러가 내부에서 다시 포인터로 변경하여 준다. 즉, 사용자가 사용하기 간단한 포인터인 셈이다

-  단, 기존의 포인터에 비해 코드를 작성할 때 번거로움이 없어지고 코드가 깔끔해진다는 장점이 있다.

 

 

 

 


 

 

 

 

틀린 부분이나 이상한 부분이 있으면 댓글로 편하게 지적해주세요!

감사합니다!



참고
씹어먹는 C++ - <2. C++ 참조자(레퍼런스)의 도입> (modoocode.com)
http://soen.kr/lecture/ccpp/cpp2/cpp2.htm // 15-4 레퍼런스

반응형

댓글