Computer >> 컴퓨터 >  >> 프로그래밍 >> C++

C++에서 오버로딩할 수 없는 함수 – 조건과 대표 사례 정리

함수 오버로딩(Function Overloading)은 메서드 오버로딩이라고도 부르며, 객체 지향 프로그래밍에서 널리 활용되는 다형성(Polymorphism) 개념이 제공하는 대표적인 기능입니다. 같은 이름의 함수를 매개변수 구성만 바꿔 여러 번 정의할 수 있어 코드의 가독성과 재사용성을 크게 높여 줍니다.

함수 오버로딩이 성립하려면 다음 조건을 충족해야 합니다.

  • 함수 이름이 서로 같아야 합니다.
  • 컴파일러가 호출 시점에 함수를 구분할 수 있도록 매개변수의 개수, 타입 또는 순서 중 하나 이상이 달라야 합니다.
  • 반환 타입은 오버로딩 판단 기준에 포함되지 않습니다. 따라서 반환 타입만 다른 함수는 오버로딩할 수 없습니다.

오버로딩 성립 여부 예시

int display(int a);
int display(float a);   // 매개변수 타입이 다르므로 오버로딩 가능

int display(int a);
float display(int a);   // 반환 타입만 다르므로 오버로딩 불가 (컴파일 오류)

C++에서 오버로딩할 수 없는 경우

1. 함수 이름과 매개변수 개수가 모두 다른 경우

이름과 매개변수 개수가 모두 다른 함수는 애초에 오버로딩 관계가 아니라 서로 완전히 별개의 함수입니다. 아래 예제의 max_two와 max_three는 이름 자체가 다르기 때문에 오버로딩으로 처리되지 않습니다.

#include <iostream>
using namespace std;

int max_two(int a, int b) {              // 매개변수 2개
    if (a > b)
        return a;
    else
        return b;
}

int max_three(int a, int b, int c) {     // 매개변수 3개
    if (a > b && a > c)
        return a;
    else if (b > c)
        return b;
    else
        return c;
}

int main() {
    cout << max_two(10, 20) << endl;
    cout << max_three(10, 20, 30) << endl;
    return 0;
}

2. 함수 이름은 같지만 반환 타입만 다른 경우

매개변수 목록이 동일한데 반환 타입만 다른 두 함수는 오버로딩할 수 없습니다. 컴파일러는 함수 호출 시점에 어떤 버전을 선택해야 할지 판단할 수 없어 'return type만 다른 함수는 오버로딩 불가'라는 오류를 발생시킵니다.

#include <iostream>
using namespace std;

int max_two(int a, int b) {
    return (a > b) ? a : b;
}

float max_two(int a, int b) {   // 오류: 반환 타입만 다름
    return (a > b) ? a : b;
}

int main() {
    cout << max_two(10, 20);
    return 0;
}

3. 정적(static) 멤버 함수와 일반 멤버 함수가 충돌하는 경우

오버로딩 조건을 모두 갖춘 것처럼 보여도, 클래스 안에서 정적 멤버 함수와 동일한 이름·동일한 매개변수 목록을 가진 비정적(non-static) 멤버 함수를 함께 선언하면 컴파일 오류가 발생합니다. 두 함수는 this 포인터 유무만 다를 뿐 외부에서 보는 시그니처가 사실상 같아 컴파일러가 구분하지 못하기 때문입니다.

#include <iostream>

class Check {
public:
    static void test(int i) { }  // 정적 멤버 함수
    void test(int i) { }         // 오류: 동일한 매개변수 목록으로 선언 불가
};

int main() {
    Check ch;
    return 0;
}

4. 기본 인수(default argument)만 다른 경우

두 함수의 이름과 매개변수 목록이 완전히 같고 한쪽에만 기본 인수가 지정된 경우에도 오버로딩은 성립하지 않습니다. 컴파일러는 이를 같은 함수의 재선언(redeclaration)으로 간주해 오류를 발생시키며, func_1(10, 20)처럼 인수를 모두 전달하는 호출 역시 어느 함수를 의미하는지 모호해집니다.

#include <iostream>
using namespace std;

int func_1(int a, int b) {
    return a * b;
}

int func_1(int a, int b = 40) {  // 오류: 기본 인수만 다름 → 재선언 오류
    return a + b;
}

int main() {
    cout << func_1(10, 20);
    return 0;
}

마무리

정리하면, C++의 함수 오버로딩은 함수 이름이 같고 매개변수 목록이 구분 가능할 때에만 성립합니다. 반환 타입의 차이, 기본 인수의 유무, 정적/비정적 멤버 함수 간의 충돌은 오버로딩으로 인정되지 않으므로 함수를 설계할 때 반드시 유의해야 합니다.