[C/C++] 함수 오버로딩(Function Overloading), 연산자 오버로딩(Operator Overloading)

할랑말랑·2026년 3월 6일

C/C++

목록 보기
7/45

함수 오버로딩(Function Overloading)

C++에서는 동일한 이름의 함수를 여러 개 정의할 수 있습니다.
그 이유는 C언어는 함수 이름으로만 함수를 구분하지만, C++은 함수 이름과 매개변수 타입 정보를 함께 사용해 구분하기 때문입니다.
이런 식으로 함수 이름 구분을 위해 내부적으로 고유한 이름을 부여하는 것을 네임 맹글링(Name Mangling) 이라고 합니다.

1. 매개변수 타입이 다른 함수 오버로딩

// 목적 : 함수 오버로딩의 개념을 매개변수 타입이 다른 경우로 이해하기
#include <iostream>
using namespace std;

void print(int a)
{
    cout << "정수 출력: " << a << endl;
}

void print(double a)
{
    cout << "실수 출력: " << a << endl;
}

int main()
{
    print(10);      // 정수 출력
    print(3.14);    // 실수 출력
    return 0;
}

// 출력결과:
// 정수 출력: 10
// 실수 출력: 3.14

2. 매개변수가 애매모호한 함수 오버로딩

// 목적: 디폴트 매개변수로 인해 호출 형태가 중복되는 경우
#include <iostream>
using namespace std;

void display(int a, int b = 5)
{
    cout << a << ", " << b << endl;
}

void display(int a)
{
    cout << a << endl;
}

int main()
{
    // display(10); // 디폴트 매개변수로 인해 두 함수 모두 호출 가능하므로 애매모호
    return 0;
}

/*
출력결과 (컴파일 에러):
error: call of overloaded 'display(int)' is ambiguous
*/

3. 매개변수의 타입만 포인터와 배열로 다른 함수 오버로딩

// 목적: 매개변수의 타입이 포인터와 배열일 때 애매모호성 발생 예시
#include <iostream>
using namespace std;

void print(int* arr)
{
    cout << "포인터 호출됨" << endl;
}

void print(int arr[])
{
    cout << "배열 호출됨" << endl;
}

int main() 
{
    int data[3] = { 1, 2, 3 };
    // print(data); // 포인터와 배열은 같은 타입으로 취급되어 애매모호
    return 0;
}

/*
출력결과 (컴파일 에러):
error: redefinition of 'void print(int*)'
배열과 포인터는 매개변수로 구분되지 않음
*/

4. 사용자 정의 타입 변환 우선

// 목적: 표준 변환이 불가능하면 사용자 정의 변환이 호출됨을 학습
#include <iostream>
using namespace std;

class MyNumber 
{
public:
    operator int() const { return 42; }
};

void print(int a)
{
    cout << "int 타입 호출됨, 값: " << a << endl;
}

void print(double a)
{
    cout << "double 타입 호출됨, 값: " << a << endl;
}

int main()
{
    MyNumber num;
    print(num); // 사용자 정의 변환을 통해 MyNumber->int로 변환됨
    return 0;
}

// 출력결과:
// int 타입 호출됨, 값: 42

오버로딩이 되지 않는 경우

함수 오버로딩이 되려면, 호출되는 함수가 분명해야 한다. 호출 시점에서 호출할 함수가 명확하지 않으면 컴파일러는 애매모호성 오류를 발생시킨다.

  • 타입 변환이 가능한 매개변수로 인해 두개 이상의 오버로딩된 함수가 호출 후보가 되는 경우
  • 디폴트 매개변수로 인해 함수 호출 형태가 중복되는 경우
  • 매개변수의 타입만 포인터와 배열로 다른 경우
  • 함수의 반환 타입만 다른 경우

함수 오버로딩의 순서

컴파일러는 최대한 변환할 수 있는 함수를 찾으려고 합니다. C++에서는 아래와 같은 명확한 우선순위 규칙에 따라 호출할 함수를 결정한다.

정확한 매칭 -> 타입 승격 변환 -> 표준 타입 변환 -> 사용자 정의 타입 변환

  • 1. 정확한 매개변수 타입 일치 : 호출 인자 타입과 매개변수 타입이 정확히 일치하는 경우

  • 2. 타입 승격 변환 : 값이 손실되지 않는 방향으로 변환하는 것을 승격이라한다.
    ex) char or short -> int , float -> double , bool -> int

  • 3. 표준 타입 변환 : 승격보다는 조금 더 광범위하다. 값 손실이 발생하는 경우도 있다. ex) int -> double , double -> int , double -> float

  • 4. 사용자 정의 타입 변환 : 클래스 타입의 변환 함수나 생성자 등을 통해 이뤄지는 변환이다.

연산자 오버로딩(Operator Overloading)

기존 연산자(+ , - , * , / 등)에 사용자 정의 타입에 대한 새로운 의미를 부여하는 것

#include <iostream>

using namespace std;

class Complex
{
private:
    double real, imag;

public:
    Complex(double r = 0, double i = 0) : real(r), imag(i) {}

    // 멤버 함수로 연산자 오버로딩
    Complex operator+(const Complex& other) const
    {
        return Complex(real + other.real, imag + other.imag);
    }

    void print() const
    {
        cout << real << " + " << imag << "i" << endl;
    }
};

int main()
{
    Complex c1(3, 4);
    Complex c2(1, 2);
    Complex c3 = c1 + c2; // c1.operator+(c2) 호출
    c3.print(); // 4 + 6i
}

오버로딩 가능한 연산자들

산술연산자

#include <iostream>

using namespace std;

class Number
{
private:
    int value;

public:
    Number(int v = 0) : value(v) {}

    // 덧셈
    Number operator+(const Number& other) const
    {
        return Number(value + other.value);
    }

    // 뺄셈
    Number operator-(const Number& other) const
    {
        return Number(value - other.value);
    }

    // 곱셈
    Number operator*(const Number& other) const
    {
        return Number(value * other.value);
    }

    // 나눗셈
    Number operator/(const Number& other) const
    {
        if (other.value == 0)
        {
            throw runtime_error("Division by zero");
        }
        return Number(value / other.value);
    }

    // 나머지
    Number operator%(const Number& other) const
    {
        return Number(value % other.value);
    }

    // 단항 마이너스
    Number operator-() const
    {
        return Number(-value);
    }

    // 단항 플러스
    Number operator+() const
    {
        return Number(+value);
    }

    int getValue() const { return value; }
};

int main()
{
    Number n1(10);
    Number n2(3);

    Number sum = n1 + n2;   // 13
    Number diff = n1 - n2;  // 7
    Number prod = n1 * n2;  // 30
    Number quot = n1 / n2;  // 3
    Number rem = n1 % n2;   // 1
    Number neg = -n1;       // -10
}
  • 복합 대입 연산자, 증감 연산자, 비교 연산자, 논리 연산자, 비트 연산자, 배열 접근 연산자 [] 등 사용할수있다.

0개의 댓글