본문 바로가기

C++

C++ 면접 질문) "언제 Reference를 쓰고 언제 Pointer를 써야 할까요?"

Reference와 Pointer의 차이점은 다음 글에서 알아보았습니다.
C++ 면접 질문) "C++에서 Reference 와 Pointer의 차이점은?"


언제 Reference를 쓰고 언제 Pointer를 써야 할 지 기준은 다음과 같습니다.

 

기준 1. Pointer가 굳이 필요없는 곳은 다 Reference 쓴다.

 

Reference가 쓰이는 곳:

  • 함수 매개변수
  • 함수 반환값
  • 임시 객체
    • 아래 예시에서 임시 객체는 리터럴이 std::string 으로 객체 변환 되면서 생성됨
    • 임시 객체 (std::string) 는 stack에 저장됨
    • 임시 객체는 reference가 const 참조로 바인딩 한다면, reference가 사용되는한 임시 객체는 살려둠 (C++ 임시 객체 수면 연장 규칙)
const std::string& getTemporaryObject() {
  return "나는 임시 객체";
}
  • 연산자 오버로딩
    • reference가 더 안전함: pointer 로 객체 접근 시 nullptr 처리가 필요함
    • C++ 관례: "대입 연산자는 const 참조를 매개변수로 사용하고 참조를 반환함"

위에서 나열된 것처럼 Reference가 쓰이는 곳은 매우 많다.


Pointer 대신 Reference를 쓰면서 얻는 장점:

  • 가독성
    • Pointer 는 deference 등 사용이 필요
  • 안전성
    • NULL 값 처리가 필요 없음

기준 2. Pointer 가 꼭 필요한 곳에서는 Pointer 를 쓰되 Smart Pointer를 쓴다

 

Pointer가 꼭 필요한 곳:

  • 동적 할당
    • unique_ptr 예시:
std::unique_ptr<int[]> res = std::make_unique<int[]>(10);
  • NULL 값
    • unique_ptr 예시:
std::unique_ptr<int[]> ptr = nullptr; // 초기화
ptr = std::make_unique<int[]>(10);

// nullptr로 리셋 (delete[] 호출)
ptr = nullptr;
  • 포인터 연산
    • raw pointer 예시 및 unique_ptr 예시:
// raw pointer

int* ptr = new int[10];
for (int i = 0; i < 5; ++i) {
  *(ptr + i) = i;
}

// smart pointer
std::unique_ptr<int[]> ptr = std::make_unique<int[]>(10);
for (int i = 0; i < 5; ++i) {
  ptr[i] = i;
}
  • 함수 포인터
    • raw pointer 예시 및 unique_ptr 예시:
void say_hello() {
  std::cout << "Hey, Man.\n";
}

void say_goodbye() {
  std::cout << "Bye, Man.\n";
}

/* raw function pointer */

void (*func_ptr)(); // function pointer 선언

func_ptr = &say_hello // 함수 주소를 대입

func_ptr(); // 함수 호출. 암시적으로 (*func_ptr)() 로 변환되어 () 연산자 호출.

func_ptr = &say_goodbye // 교체가 바로 이뤄짐. 함수 포인터는 delete 불필요.

/* smart function pointer */

auto func_ptr = std::make_unique<std::function<void()>>(say_hello);
// std::make_unique 사용 시 type 추론 시 명확하니 간편한 auto 사용
// 단일 std::function 객체를 할당하므로 인자에 바로 함수 대입

(*func_ptr)();
// std::function의 () 연산자 호출
// func_ptr() 은 unique_ptr의 () 연산자가 호출

*func_ptr = say_goodbye;

추가 질문:

- 그러면 어떨 때 reference 쓰고 어떨 때 value를 써야 할까요?