SW/C++

C++11 : 함수 오버로딩에 대해 알아볼까요? (개념 및 예제)

얇은생각 2018. 12. 31. 07:30
반응형

오버로딩은 사전 상에서는 짐을 많이 싣는다는 의미를 가지고 있습니다. 함수 오버로딩은 과연 무슨뜻일까요? 단어의 의미는 함수를 짐처럼 많이 싣는다고 생각할 수 있습니다.


A 함수, B 함수, C 함수가 있다고 가정하겠습니다. 여러 함수를 하나의 장소, 즉 하나의 함수 이름에 쌓는 것을 함수 오버로딩이라고 설명할 수 있습니다. 함수 오버로딩은 객체지향의 특징 중 하나인 다형성이라는 개념과 일맥상통합니다. 함수의 다형성이란 하나의 함수를 다양한 형태로 나타내는 것을 의미합니다.


다양한 함수를 결합하는 방식에 대해 알아보겠습니다.


#include <iostream>
using namespace std;
 
class Chulsoo
{
public:
    void Eat(void);
    void Eat(int SteakNum);
    void Eat(double SteakWeight);
    void Eat(int SteakNum1, int SteakNum2);
};
 
int main(void)
{
    Chulsoo chulsoo;
    chulsoo.Eat();
    chulsoo.Eat(20000);
    chulsoo.Eat(500.5);
    chulsoo.Eat(2000030000);
    return 0;
}
 
void Chulsoo::Eat(void)
{
    cout << "철수는 스테이크를 먹는다" << endl;
}
 
void Chulsoo::Eat(int SteakNum)
{
    cout << "철수는 " << SteakNum << "원 짜리 스테이크를 먹는다" << endl;
}
 
void Chulsoo::Eat(double SteakWeight)
{
    cout << "철수는 " << SteakWeight << "g 짜리 스테이크를 먹는다" << endl;
}
 
void Chulsoo::Eat(int SteakNum1, int SteakNum2)
{
    cout << "철수는 " << SteakNum1 << "원 짜리 스테이크를 먹고, ";
    cout << SteakNum2 << "원 짜리 스테이크를 먹는다" << endl;
}
cs


예제를 보시면 다형성과는 거리가 멀다는 것을 알 수 있습니다. 4가지 함수가 서로 다른 형태이면서 다른 이름으로 선언되었으므로 다형성의 조건을 충족하지 않습니다. 따라서 철수가 먹는 행위를 서로다른 4개의 함수로 호출해야 합니다.


오버로딩 구현하려면 하나의 함수 이름으로 서로다른 형태를 가지는 함수를 표현해야 합니다. 다음 예제를 보도록 하겠습니다.


#include <iostream>
using namespace std;
 
class Chulsoo
{
public:
    void Eat(void);
    void Eat(int SteakNum);
    void Eat(double SteakWeight);
    void Eat(int SteakNum1, int SteakNum2);
};
 
int main(void)
{
    Chulsoo chulsoo;
    chulsoo.Eat();
    chulsoo.Eat(20000);
    chulsoo.Eat(500.5);
    chulsoo.Eat(2000030000);
    return 0;
}
 
void Chulsoo::Eat(void)
{
    cout << "철수는 스테이크를 먹는다" << endl;
}
 
void Chulsoo::Eat(int SteakNum)
{
    cout << "철수는 " << SteakNum << "원 짜리 스테이크를 먹는다" << endl;
}
 
void Chulsoo::Eat(double SteakWeight)
{
    cout << "철수는 " << SteakWeight << "g 짜리 스테이크를 먹는다" << endl;
}
 
void Chulsoo::Eat(int SteakNum1, int SteakNum2)
{
    cout << "철수는 " << SteakNum1 << "원 짜리 스테이크를 먹고, ";
    cout << SteakNum2 << "원 짜리 스테이크를 먹는다" << endl;
}
cs


위 예제는 처음 제시한 예제와 실행 결과는 같습니다. 하지만 함수 오버로딩을 잘 사용하였습니다. 같은 이름으로 다양한 기능을 수행했는데 어떤 함수를 호출해야하는지 어떻게 알까요?


바로 매개변수입니다. argument라고도 합니다. 매개변수 목록이란 매개변수 개수와 자료형의 조합입니다. 매개변수 목록을 보면 void, int, double 등으로 자료형이나 개수가 서로 다릅니다.


함수를 호출할 때 전달하는 인자의 개수와 자료형에 따라서 일치하는 함수를 호출하는 것입니다. 


#include <iostream>
using namespace std;
 
class Chulsoo
{
public:
    void Eat(void);
    int Eat(int SteakNum);
    double Eat(double SteakWeight);
    int Eat(int SteakNum1, int SteakNum2);
    double Eat(int SteakWeight1, int SteakWeight2);
};
 
int main(void)
{
    Chulsoo chulsoo;
    chulsoo.Eat();
    chulsoo.Eat(20000);
    chulsoo.Eat(500.5);
    chulsoo.Eat(2000030000); // 어떤 함수를 호출해야 할까?
    return 0;
}
 
void Chulsoo::Eat(void)
{
    cout << "철수는 스테이크를 먹는다" << endl;
}
 
int Chulsoo::Eat(int SteakNum)
{
    cout << "철수는 " << SteakNum << "원 짜리 스테이크를 먹는다" << endl;
    return SteakNum;
}
 
double Chulsoo::Eat(double SteakWeight)
{
    cout << "철수는 " << SteakWeight << "g 짜리 스테이크를 먹는다" << endl;
    return SteakWeight;
}
 
int Chulsoo::Eat(int SteakNum1, int SteakNum2)
{
    cout << "철수는 " << SteakNum1 << "원 짜리 스테이크를 먹고, ";
    cout << SteakNum2 << "원 짜리 스테이크를 먹는다" << endl;
    return SteakNum2;
}
 
double Chulsoo::Eat(int SteakWeight1, int SteakWeight2)
{
    cout << "철수는 " << SteakWeight1 << "g 짜리 스테이크를 먹고, ";
    cout << SteakWeight2 << "g 짜리 스테이크를 먹는다" << endl;
    return SteakWeight2;
}
cs


eat 함수의 반환형을 다양하게 변경하였습니다. 함수의 이름 매개변수와 자료형이 같으면서 반환형만 다른 함수를 새로 선언하였습니다. 이것을 실행하면 오류가 발생합니다. 


에러 목록은 오버로드된 함수와 반환 형식만 다르다고 확인이 됩니다. 결국 함수 오버로딩은 함수 이름이 같지만 매개변수 목록은 달라야 합니다. 만약 반환형만 다르다면 오류가 발생합니다. 컴파일러가 어떤 함수를 가르키는지 알 수 없기 때문이죠.


정리를 한다면 함수 오버로딩은 같은 이름으로 서로 다른 형태의 여러 함수를 만들 수 있게 합니다. 이것은 C++ 함수의 다형성을 지원한다는 의미입니다. 그러나 C++ 컴파일러는 함수 이름과 매개변수 목록으로 함수를 구분하므로, 함수 이름을 같되 매개변수 목록은 다르게 선언해야 합니다. 만일 함수 이름도 같고 매개변수도 목록도 같다면 컴파일러가 어떤 함수를 호출해야 할지 알 수 없어 오류가 발생합니다.

반응형