본문으로 바로가기

OOP의 이해 - ⑥ Function overloading

category Computer Science/C++ 2021. 10. 13. 19:59

OOP의 이해 - ⑥ Function overloading

Function overloading

함수의 이름이 같고 파라미터가 다를때 name mangling을 통해서 컴파일러가 서로 다른 함수로 만들어준다는 개념이다. 아래의 코드를 살펴보자


컴파일러가 foo(int n) 함수를 _Z3fooifoo(double d) 함수는 _Z3food 함수로 만들어 이름이 서로 다른 함수로 변환한 것을 확인할 수 있다.

 

그래서 function overloaing을 static polymorphism 이라고도 부른다. 그 이유는 어떤 함수가 호출될지 컴파일 시간에 결정되기 때문이다. 그리고 function overloading은 멤버함수에서도 동일하게 동작한다.

Operator overloading

C++에서 사용하는 연산자들도 마찬가지로 오버로딩을 통해서 재정의할 수 있다. 아래와 같이 복소수 구조체를 만들어 보자.

struct complexNum {
    double real;    // 실수
    double image;   // 허수

    complexNum(double r, double i) : real{ r }, image{ i } {}
    void print() const
    {
        std::cout << real << " " << image << "i" << std::endl;
    }
};
complexNum operator+ (const complexNum& lhs, const complexNum& rhs)
{
    return complexNum(lhs.real + rhs.real, lhs.image + rhs.image);
}
int main()
{
    complexNum c1{ 1, 1 }; // 1 + i
    complexNum c2{ 1, 2 }; // 1 + 2i

    complexNum c3{ c1 + c2 }; // 2 + 3i

    return 0;
}

complexNum 구조체에서 complexNum객체들 간의 + 연산은 기본적으로 정의되어 있지 않기 때문에 복소수 간의 덧셈을 위와 같이 별도로 정의할 수 있다. 덧셈 뿐만 -,*,/,% 등의 산술 연산들을 모두 재정의 할 수 있다.

산술 연산 외에 ==, <와 같은 비교연산자나 <<와 같이 스트림 연산자도 재정의할 수 있다. 아래의 코드를 참고하자.

class Cat {
public:
    Cat(std::string name, int age) : mName{ std::move(name) }, mAge{ age } {}
    const std::string name() const 
    {
        return mName;
    }
    int age() const 
    {
        return mAge;
    }
    void print() 
    {
        std::cout << mName << " " << mAge << std::endl;
    }

private:
    std::string mName;
    int mAge;
};

bool operator==(const Cat& lhs, const Cat& rhs)
{
    return (lhs.name() == rhs.name()) && (lhs.age() == rhs.age());
}
bool operator<(const Cat& lhs, const Cat& rhs)
{
    return lhs.age() < rhs.age();
}
std::ostream& operator<<(std::ostream& os, const Cat& c)
{
    return os << c.name() << " " << c.age();
}
int main()
{
    Cat kitty("kitty", 3);
    Cat nabi("nabi", 5);

    // == operator
    if(kitty == nabi)
    {
        std::cout << "kitty and nabi are the same" << std::endl;
    }
    else
    {
        std::cout << "kitty and nabi are't the same" << std::endl;
    }
    // < operator
    if (kitty < nabi)
    {
        std::cout << "kitty is younger than nabi" << std::endl;
    } 
    else
    {
        std::cout << "kitty isn't younger than nabi" << std::endl;
    }
    // << operator
    std::cout << kitty << std::endl;

    return 0;
}

출력 결과

kitty and nabi are't the same
kitty is younger than nabi
kitty 3

몇가지 산술 연산자 재정의를 응용하면 STL 함수들과 함께 강력한 C++ 기능들을 활용할 수 있다. 다음과 같은 상황을 예로들 수 있다.

//Cat class는 위와 동일
int main()
{
    std::vector<Cat> Cats{ {"kitty", 3},{"nabi", 5},{"tom", 1} };
    std::sort(Cats.begin(), Cats.end());
    for (const auto& cat : Cats)
        std::cout << cat << std::endl;

    return 0;
}

출력 결과

tom 1
kitty 3
nabi 5

<연산이 정의되어 있기 때문에 sort함수를 활용하여 나이를 기준으로 정렬할 수 있고, << 연산자를 활용하여 출력까지 간결하게 구현할 수 있다. 

 


출처: https://www.youtube.com/channel/UCHcG02L6TSS-StkSbqVy6Fg