본문 바로가기

Programming Languages/C++

[함수]-함수의 다중정의

다중정의(overloading)란 동일한 이름에 대하여 여러 가지 의미를 부여하는 것이다. C++ 언어에서는 함수를 다중정의할 수 있다. 즉, 동일한 이름을 갖는 함수를 여러 개 정의할 수 있다. 함수를 다중정의하는 것은 동일한 개념의 처리를 다양한 데이터나 객체에 대해 해야 할 경우 쓰인다. 각각의 대상에 맞는 처리방법을 같은 이름을 갖는 함수들로 만듦으로써 의미를 일맥상통하게 만들어 주는 효과가 있다. 함수를 다중정의한 경우, 사용되는 함수가 같은 이름을 가지고 있는 여러 함수 중에서 어느 함수를 의미하는가를 구분할 수 있어야 한다. 구분의 기준은 인수의 개수 및 인수의 자료형이다. 컴파일러는 이를 근거로 동일한 이름을 갖는 여러 함수 중에서 어느 함수를 사용한 것인지를 알아낸다. 반환 자료형은 구분 기준에 포함되지 않는다는 점에 주의해야 된다.

시간에 대한 계산을 하는 [소스코드 3-9] TimeCalc.cpp에 대하여 살펴보자. 이 프로그램에서는 시간 길이를 표현하기 위해 구조체 TimeRec을 선언하였다. 또한 시간의 합을 계산하기 위해 AddTime()이라는 함수를 정의하였다.

// 소스코드 3-9 : TimeCalc.cpp
#include <iostream>
using namespace std;

struct TimeRec {
	int hours;
	int minutes;
};

// 시간을 더하는 함수
// 인수 TimeRec &t1  : 누계할 시간
//      const TimeRec &t2  : 더할 시간
// 반환값 없음
void AddTime(TimeRec& t1, const TimeRec& t2) {
	t1.minutes += t2.minutes;
	t1.hours += t2.hours + t1.minutes / 60;
	t1.minutes %= 60;
}

// 시간을 더하는 함수
// 인수 TimeRec &t1  : 누계할 시간
//      int minutes  : 더할 분 단위의 시간
// 반환값 없음
void AddTime(TimeRec& t, int minutes) {
	t.minutes += minutes;
	t.hours += t.minutes / 60;
	t.minutes %= 60;
}

int main() {
	TimeRec tRec1 = { 2, 30 };
	TimeRec tRec2 = { 1, 45 };

	cout << tRec1.hours << "시간" << tRec1.minutes << "분 + ";
	cout << tRec2.hours << "시간" << tRec2.minutes << "분 = ";
	AddTime(tRec1, tRec2);
	cout << tRec1.hours << "시간" << tRec1.minutes << "분" << endl;

	cout << tRec1.hours << "시간" << tRec1.minutes << "분 + ";
	cout << "135분 = ";
	AddTime(tRec1, 135);
	cout << tRec1.hours << "시간" << tRec1.minutes << "분" << endl;
	return 0;
}

====== 결과 ======
2시간30분 + 1시간45분 = 4시간15분
4시간15분 + 135분 = 6시간30분

TimeCalc.cpp에는 AddTime()이라는 함수가 2개 정의되어 있다. 하나는 두 인수가 모두 TimeRec&형이고, 다른하나는 TimeRec&형 인수 1개와 int형 인수 1개로 구성되어 있다. 

함수 다중정의는 명확하게 구분하여 호출할 수 있게 해야 한다.

함수를 다중정의할 때에는 모호하게 정의되는 것을 조심하여야 한다. 예를 들어

int f(int a) // ①

{ ... }

int f(int a, int b) // ②

{ ... }

와 같이 정의하면 호출할 때 인수의 개수에 따라 어느 함수를 호출할 것인지 명확하게 구분할 수 있다. 인수가 1개면 ①, 2개면 이다. 그러나

int g(int a) //

{ ... }

int g(int a, int b=100) //

{ ... }

이라고 정의하면 g(10)이라고 호출하였을 때 어느 함수를 호출할 것인지가 명확하지 않다. ③을 호출한 것이라고 볼 수도 있고, b에 디폴트 인수를 적용하여 ④를 호출한 것으로 볼 수도 있기 때문이다. 따라서 컴파일러는 이렇게 호출한 문장을 오류로 처리한다.