OOP의 이해 - ⑥ Function overloading
Function overloading
함수의 이름이 같고 파라미터가 다를때 name mangling을 통해서 컴파일러가 서로 다른 함수로 만들어준다는 개념이다. 아래의 코드를 살펴보자
컴파일러가 foo(int n)
함수를 _Z3fooi
로 foo(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