프로그래밍C++ 개발자

C++에서 함수 오버로딩(함수 중복 정의)과 오버로드 해상도(중복 정의 해상도)는 무엇인가요? 오버로딩, 기본 인수 및 참조를 혼합할 때 어떤 특성이 있나요?

Hintsage AI 어시스턴트로 면접 통과

답변

문제의 역사

C++는 초기에 함수 오버로딩을 지원하는 언어로 설계되었습니다. 이는 동일한 이름의 여러 함수를 다양한 매개변수로 선언할 수 있는 기능을 제공합니다. 이는 읽기 쉽고 편리한 API를 만드는 데 도움이 됩니다.

문제

동일한 이름을 가진 함수가 많아지면, 컴파일러는 모든 오버로드 된 함수에서 적절한 구현을 선택해야 합니다. 이때 인수의 유형, 변환, 기본 매개변수 및 참조를 고려해야 합니다. 부주의한 오버로딩을 사용할 경우 모호성과 찾기 힘든 오류가 발생합니다.

해결 방법

컴파일러는 인수의 최적 일치, 유형 일치의 정확성 및 최소한의 변환을 기반으로 함수를 선택합니다. 하지만 중요한 변환이나 기본 인수가 있는 경우 예상치 못한 모호성이 발생할 수 있습니다.

코드 예시:

void foo(int x); void foo(double x); void foo(int x, int y = 0); foo(5); // void foo(int x)를 호출합니다. 정확하게 일치함 foo(5.2); // void foo(double x)를 호출합니다 foo(5, 6); // void foo(int x, int y)를 호출합니다

주요 특징:

  • 모든 함수는 고유한 매개변수 유형/수로 구별되어야 합니다
  • 오버로드된 함수의 기본 인수는 오버로드 해결을 혼란스럽게 만들 수 있습니다
  • 참조 및 유형 변환은 모호성을 유발할 수 있습니다

함정 질문들

반환 타입만으로 함수를 오버로딩할 수 있나요?

아니요. 오버로딩은 오직 매개변수의 유형과 수에 의해서만 가능하며, 반환 타입은 오버로드 해상도에 참여하지 않습니다.

int foo(); double foo(); // 오류: 반환 타입만으로 오버로딩할 수 없습니다!

모든 매개변수가 변환 가능할 경우, 컴파일러는 어떤 오버로드된 함수를 선택하나요?

컴파일러는 "최적 일치" 즉, 필요한 최소한의 유형 변환이거나 정확한 일치를 요구하는 함수를 선택합니다. 모호성이 존재할 경우, 코드는 컴파일되지 않습니다.

void bar(int); void bar(long); bar(1); // int가 정확한 일치: bar(int)을 호출합니다

기본 인수와 일반 오버로딩을 혼합할 수 있나요?

가능하지만 함수의 시그니처가 겹치는 경우 호출의 모호성을 초래할 수 있습니다.

void test(int x); void test(int x, int y = 10); test(5); // 오류: 모호성 — 두 함수 모두 적합합니다

일반적인 오류 및 반패턴

  • 기본 인수를 가진 오버로드된 함수가 겹치는 경우
  • 명백하지 않은 유형 변환(예: double → int)
  • 반환 타입만으로 오버로딩 시도

실제 사례

부정적인 케이스

라이브러리에서 기본 인수가 겹치는 오버로드된 함수들이 발견되어, 코드 업데이트 시 컴파일 오류가 발생합니다.

장점:

  • 처음에는 쉽게 함수를 호출할 수 있습니다

단점:

  • 유사한 인수로 새로운 오버로드를 추가할 때 발생하는 오류
  • 오버로드 선택에 따른 예측 불가능한 동작

긍정적인 케이스

프로젝트에서 기본 인수를 가진 오버로딩을 혼합하지 않거나, 기본 값을 가진 함수 또는 고유한 매개변수로만 오버로딩하는 규칙을 도입했습니다.

장점:

  • 명시적이고 예측 가능한 동작
  • 유지 보수 시 오류 감소

단점:

  • 함수 API 시그니처가 조금 더 길고 다소 복잡해집니다