[C++] 함수 오버로딩(Function Overloading)

[C++] 함수 오버로딩(Function Overloading)

안녕하세요 이번 글에서는 함수 오버로딩에 대해 알아보겠습니다.

우선 아래 코드의 문제점을 무엇일까요?

#include <iostream>

using namespace std;

void swap(int *x, int *y)
{
	int iTemp = *x;
	*x = *y;
	*y = iTemp;
}

void main()
{
	int a = 1, b = 2;
	double c = 3.3, d = 4.4;

	swap(&a, &b);
	cout << "a : " << a << endl;
	cout << "b : " << b << endl;

	swap(&c, &d);
	cout << "c : " << c << endl;
	cout << "d : " << d << endl;

	system("pause");
}

swap(&c, &d);를 보시면 double형 주소를 인자로 전달합니다. 하지만 swap 함수는 int 포인트로 인자를 받으므로 “double *”가 “int *”로 형변환이 되지 않아 에러가 생깁니다.

그렇다고 아래와 같이 강제 형변환을 할 수도 없는 노릇입니다.

swap((int*)&c, (int*)&d); // 안됨

C++에서는 같은 이름의 함수가 여러 개 올 수 있는데, 이것을 함수 오버로딩(function overloading)이라고 합니다.
그렇다고 규칙 없이 같은 이름을 가진 함수를 여러 개 만들 순 없습니다.
C++에서는 함수를 구별하기 위해 함수명과 매개 변수 갯수매개 변수 타입을 이용합니다.

아래의 함수는 함수 오버로딩이 가능합니다.

void swap(int *x, int *y)
{
	int iTemp = *x;
	*x = *y;
	*y = iTemp;
}

// 매개 변수 갯수를 이용한 함수 오버로딩
void swap(int *x, int *y, int *z)
{
	int iTemp = *x;
	*x = *y;
	*y = *z;
	*z = iTemp;
}
// 매개 변수 타입을 이용한 함수 오버로딩
void swap(double *x, double *y)
{
	double dTemp = *x;
	*x = *y;
	*y = dTemp;
}

위 경우는 같은 함수명을 가진 함수들이 매개 변수의 갯수와 타입으로 함수 오버로딩 된 예제입니다.
안되는 경우는 어떤 경우일까요? 반환형으로 함수를 구별 할 수 없습니다.

void swap(int *x, int *y)
{
	int iTemp = *x;
	*x = *y;
	*y = iTemp;
}

// 위 함수와 반환형이 다름
bool swap(int *x, int *y)
{
	int iTemp = *x;
	*x = *y;
	*y = iTemp;

	return true;
}

이 경우에 함수를 호출 할 때 어떤 함수를 호출해야 할지 명확하지 않습니다.

swap(&a, &b); // void swap(int *x, int *y)와 bool swap(int *x, int *y) 중 어떤것을 호출?

이런 경우를 모호하다라고 합니다. 함수 호출이 모호한 경우는 아래와 같이 함수 오버로딩 시 발생할 수 있습니다.

void swap(int *x, int *y)
{
	int iTemp = *x;
	*x = *y;
	*y = iTemp;
}

void swap(char *x, char *y)
{
	char iTemp = *x;
	*x = *y;
	*y = iTemp;
}

위와 같은 경우 함수 오버로딩은 가능합니다.
하지만 아래와 같이 swap 함수를 호출하면 어떤 함수를 호출할지 판단하지 못해 모호한 상황이 발생하여 컴파일 에러가 발생합니다.

void main()
{
	long h = 8, i = 9;

	// void swap(int *x, int *y)
	// void swap(char *x, char *y)
	// 모두 사용 가능
    
	swap(&h, &i); 
	cout << "h : " << h << endl;
	cout << "i : " << i << endl;

	system("pause");
}