728x90

Overloading (오버 로딩)에는 Function Overloading과 Operator Overloading이 있다. 

 

 

Function Overloading  (함수 오버 로딩)

Function의 이름이 같고 파라미터가 다를 때 name magling을 이용하여 argument에 따라 맞는 함수를 호출해주는 것을 말한다. Function Overloading에는 Static Polymorphism (정적 다형성)과 Dynamic Polymorphism (동적 다형성)이 있다. Static Polymorphism은 함수가 Compile-time에 binding이 되는 것을 말한다. Dynamic Polymorphism은 함수들이 Run-time에 바인딩이 되는 것이다. 주로 virtual 키워드를 통해 만들어 낸다. 해당 내용은 Class의 Inheritance (상속) 포스팅에서 자세히 다루도록 한다. 

 

함수 오버 로딩을 구현한 코드와 함께 설명을 하겠다. 

#include <iostream>

void function(int n)
{
    std::cout << "function(int)" << std::endl;
}

void function(double d)
{
    std::cout << "function(double)" << std::endl;
}

int main()
{
    function(3);
    function(3.18);
}

위 코드는 함수명 function인 함수를 오버 로딩한 코드이다. main함수에서 각각 integer형 상수와 double 상수를 Argument로 주고 호출을 하면 Argument에 따라서 맞는 함수를 호출하게 된다.  위 코드를 어셈블리 코드로 변환을 해서 보면 더 명확하게 확인할 수 있다. 

어셈블리 코드를 보게 되면 function(int)는 _Z8functioni, function(double)은 _Z8functiond로 name mangling에 의해 변환이 되었다. 그리고 main함수를 보게 되면 각각 다른 함수를 호출하는 것을 확인할 수 있다. 

 

 

Operator Overloading (연산자 오버 로딩)

Operator Overloading은 말 그래로 operator (연산자)에 대해서 overloading을 한다. 예를 들면 산술 연산자 (+, -, etc.), 비교 연산자 (>, <, ==)과 같은 연산자들에 대해서 overloading을 하는 것을 말한다. Operator Overloading이 중요한 이유는 특정 연산자는 STL과 연계하여 강력한 C++ 개발을 지원하기 때문이다. 

#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
class Dog
{
public:
    Dog(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() const
    {
        std::cout << mName << " " << mAge << std::endl;
    }

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

bool operator==(const Dog& lhs, const Dog& rhs)
{
    return lhs.age() == rhs.age() && lhs.name() == rhs.name();
}

bool operator<(const Dog& lhs, const Dog& rhs)
{
    if (lhs.age() < rhs.age())
        return true;
    return false;
}

std::ostream& operator<<(std::ostream& os, const Dog& c)
{
    return os << c.name() << " " << c.age();
}

int main()
{
    Dog choco{"choco", 10};
    Dog cream{"cream", 5};
    std::vector<Dog> dogs;
    // add dogs....
    std::sort(dogs.begin(), dogs.end());
    //sort를 하는 기준은  comparison operator이 된다. 
    
    std::cout << choco == cream << std::endl; //0
    
    std::cout << cream < choco << std::endl; //1
    
    std::cout << choco;
    //choco 10

}

 

쉽게 생각하면 연산자 오버로딩은 이름을 오버 로딩하고자 하는 operator'연산자'로 지정을 해주면 된다. 위 코드를 보면 쉽게 함수 연산자에 대해서 알 수 있다. 위 코드에서 comparison operator '<'를 오버 로딩을 하게 되면 STL feature인 sort함수를 Dog객체가 담긴 vector에 그대로 적용할 수 있다. 왜냐하면 sort함수는 비교 연산자를 통해서 정렬이 되게 되는데 연산자 오버 로딩을 통해 객체 간의 정렬이 이루어지게 할 수 있다. 

+ Recent posts