C++ Pass-by-Pointer vs Pass-by-Reference

TAEJUN KIM·2021년 7월 28일

C++

목록 보기
1/1

출처: https://www.geeksforgeeks.org/passing-by-pointer-vs-passing-by-reference-in-c/

Pass-by-Value와 Pass-by-pointer / Reference 를 쉽게 구분하려면
호출된 함수에서 값 변경이 호출한 함수에 영향을 미치는가의 유무로 나눌 수 있다.

그러다 든 의문은 Pass-by-Pointer 와 Pass-by-Referecne의 차이점과 써야하는 상황(?)이였다.
먼저 포인터와 레퍼런스의 차이점을 간략히 비교한 뒤
Pass-by-Pointer 와 Pass-by-Referecne 의 차이점을 알아본다.

포인터와 레퍼런스의 차이점

Reference 는 말 그대로 같은 Object에 다른 이름을 붙인 것이다. 따라서 포인터처럼 NULL 값이 올 수 없어서 더 안전하다.

  1. 포인터는 다른 값으로 재 할당이 가능하다. 하지만 레퍼런스는 선언과 동시에 별명을 붙여주고 그 이후 레퍼런스가 가르키는 객체에 대한 변경이 불가능하다.( a의 레퍼런스 C를 코드상에서 b의 레퍼런스로 변경하는 것이 불가능하다는 얘기이다)

  2. 포인터는 NULL값을 할당받을 수 있다. 레퍼런스는 불가하다.

  3. 포인터는 증감연산을 통해 가르키는 배열을 iterate 할 수 있다. 레퍼런스는 배열을 가르킨다면 index 방식으로 iterate 해야한다.

  4. 포인터는 메모리를 가르키는 변수이다. 근데 메모리상에서 포인터도 존재해야하므로 메모리 0X100번주소에 할당된 포인터의 변수 값이 0X200번주소인 식이다. 레퍼런스는 추종하는 객체와 동일한 메모리 주소를 가진다. /

  5. 클래스나 구조체에서 멤버에 접근할때 포인터는 -> (Arrow Operator) 를 쓰지만 레퍼런스는 . (Dot Operator) 을 쓴다.

  6. 포인터가 가르키는 값은 *로 Deference 된다. 레퍼런스는 그냥 쓰면 된다.

Pass-by-Pointer 와 Pass-by-Referecne 의 차이점

'추종하는 값을 수정 가능한가 아닌가로 나눌 수 있다' 로 정리하면 될 것같다.

Parameter passing 에서 레퍼런스가 선호된다. 하지만 이는 "재할당"이 필요하지 않을 때 얘기이다. 전반적으로 할 수 있으면 레퍼런스텍스트를 쓰고 포인터를 꼭 써야만 하는 상황에는 포인터를 쓰라고 할 수 있겠다.

Reference로 매개변수를 받는 경우/ 리턴하는 경우

출처: 씹어먹는 C++ 강의<2. C++ 참조자(레퍼런스)의 도입>

기본적으로 함수에 파라미터를 전달할때 복사가 일어난다.

int function(){
	int a = 2;
    return a;
}

int main(){
	int b = function();
    return 0;
}

변수 a의 값 2를 b에 복사 하여 할당함.
function 함수가 종료되면 a는 메모리에서 소멸된다.

int& function() {
  int a = 2;
  return a;
}

int main() {
  int b = function();
  b = 3;
  return 0;
}

변수 a의 레퍼런스를 b에 복사하여 할당함.
function 함수가 종료되면 a는 메모리에서 소멸된다.
그럼 a의 레퍼런스도 없어질 것이다. 그럼 b는?

Undefined Behavior이다. Dangling reference

int& function(int& a) {
  a = 5;
  return a;
}

int main() {
  int b = 2;
  int c = function(b);
  return 0;
}

c에다 b의 값을 대입하는거랑 동일하다.

int function() {
  int a = 5;
  return a;
}

int main() {
  int& c = function();
  return 0;
}

이또한 Dangling reference 이다.

하지만 예외가 하나 존재한다.

int function() {
  int a = 5;
  return a;
}

int main() {
  const int& c = function();
  std::cout << "c : " << c << std::endl;
  return 0;
}

const int& 처럼 const reference로 받으면 a의 생명이 레퍼런스가 소멸될 때 까지 연장된다.

정리

함수에서 값 리턴 ( int f() )함수에서 레퍼런스 리턴 ( int& f() )
값 타입으로 받는경우
(int a = f())
a 로 값이 복사된다a 로 값이 복사된다
다만 지역변수의 레퍼런스를 리턴하지(중간에 소멸되는거) 않도록 주의 Dangling reference
reference 타입으로 받는 경우
(int& a = f())
컴파일 오류 ( 간혹 안나는 경우도 있는데 Undefined Behavior 이다. 심각한 버그를 초래할 수 있음)가능하다
다만 지역변수의 레퍼런스를 리턴하지(중간에 소멸되는거) 않도록 주의 Dangling reference
const reference 타입으로 받는 경우
(const int& a = f())
가능가능. 다만 마찬가지로 지역 변수의 레퍼런스를 리턴하지 않도록 주의
profile
前) 컴퓨터 공학과 학생 現)취준 백수

0개의 댓글