[c++] 함수 오버로딩과 이름 이질성

C++은 함수 오버로딩이라는 기능을 제공하여 서로 다른 매개변수 목록을 가진 둘 이상의 함수를 정의할 수 있게 합니다. 이를 통해 동일한 이름으로 여러 함수를 다양한 매개변수로 호출할 수 있습니다. 그러나 때로는 함수 오버로딩이 예상과 다르게 동작할 수 있는데, 이는 이름 이질성 때문입니다.

함수 오버로딩

함수 오버로딩은 동일한 이름을 가진 함수가 서로 다른 매개변수 목록을 가질 때 발생합니다. 예를 들어, 다음은 두 개의 오버로드된 함수입니다.

void printNumber(int num) {
    std::cout << "정수: " << num << std::endl;
}

void printNumber(double num) {
    std::cout << "실수: " << num << std::endl;
}

위 예시에서 printNumber라는 이름을 가진 함수는 정수와 실수를 매개변수로 받아 각각 다른 동작을 수행합니다.

이름 이질성

이름 이질성은 C++ 컴파일러가 동일한 이름의 오버로드된 함수를 해석하는 방법에 대한 혼동을 일으키는 현상을 말합니다. 컴파일러는 함수 호출 시 인자의 타입으로 어떤 함수를 호출할지 결정해야 합니다. 그러나 때로는 이 과정에서 예상과 다른 함수가 호출될 수 있습니다.

함수 오버로딩 시 이름 이질성이 발생하는 여러 상황 중 가장 흔한 예시는 포인터와 참조에 의해 발생합니다.

void foo(int x) {
    std::cout << "int 버전: " << x << std::endl;
}

void foo(int* x) {
    std::cout << "포인터 버전: " << *x << std::endl;
}

int main() {
    int x = 5;
    foo(&x);    // 어떤 함수가 호출될까요?
}

위의 코드에서 foo(&x)를 호출하면 컴파일러는 int형 포인터를 받는 함수를 호출해야 하는지, 아니면 int를 받는 함수를 호출해야 하는지 혼돈을 겪을 수 있습니다.

해결 방법

함수 오버로딩의 이름 이질성을 피하기 위해 명시적 형 변환을 사용할 수 있습니다. 함수 호출 시 명시적으로 올바른 매개변수 타입으로 변환하여 이질성을 해소할 수 있습니다.

int x = 5;
foo(static_cast<int*>(&x));  // int* 타입으로 명시적 형 변환

명시적 형 변환이 없이는 컴파일러가 함수 호출을 해석하는 데 혼돈을 느낄 수 있기 때문에 명시적 형 변환이 중요합니다.

결론

C++ 함수 오버로딩은 다양한 매개변수 목록으로 여러 함수를 동일한 이름으로 정의할 수 있게 해주지만, 이름 이질성이라는 현상으로 인해 함수 호출 시 혼동을 줄 수 있습니다. 명시적 형 변환은 이러한 혼동을 방지하기 위해 중요한 도구 중 하나입니다.

위에서 설명한 것처럼 함수 오버로딩과 이름 이질성에 대한 이해는 C++의 중요한 측면 중 하나이므로, C++ 프로그래밍에 있어서 이를 주의 깊게 다루어야 합니다.

참고 문헌: