function overloading, operator overloading

김대익·2022년 3월 4일

function overloading은
함수 이름이 같지만 파라미터가 다른경우
(ex. func(1), func("hi"))
name mangling을 이용해 컴파일러가 서로 다른 함수로 만들어주는 것

다른 말로는 static polymorphism이라고도 불린다.
그 이유는 어떤 함수가 binding될지 compile시간에 결정이 되기 때문

반대되는 개념으로 dynamic polymorphism이 있고
그 이유는 어떤 함수가 binding될지 runtime시간에 결정이 된다.
이는 virtual이라는 키워드를 통해 만들어진다.


앞에서는 function overloading을 free function에 대해서 구현했지만
class내부의 member function으로도 구현이 가능하다.


operator overloading
*, %, /, new, delete, [], ()등을 overloading한다는 것

복소수를 예를 들어 설명하면

#include <iostream>
using namespace std;
struct complexNum {
	double real;
    double imag;
    
    complexNum(double r, double i): real{r}, imag{i} {};
    void print() const {
    	cout << real << " " << imag << "i" << endl;
    }
};

int main() {
	complexNum c1{1, 1};
    complexNum c2{1, 2};
    complexNum c{c1 + c2};
    c.print();
}

이를 바로 빌드하면 에러가 뜨는데
complexNum c{c1 + c2};의 operator인 "+"가 정의되어 있지 않기 때문이다.

#include <iostream>
using namespace std;
struct complexNum {
	double real;
    double imag;
    
    complexNum(double r, double i): real{r}, imag{i} {};
    void print() const {
    	cout << real << " " << imag << "i" << endl;
    }
};

complexNum operator+(const complexNum& lhs, const complexNum& rhs) {
	complexNum c{lhs.real+rhs.real, lhs.imag+rhs.imag}
    return 0;
}

int main() {
	complexNum c1{1, 1};
    complexNum c2{1, 2};
    complexNum c{c1 + c2};
    c.print();
}

위와 같이 operator+로 "+"를 정의할수있다.


#include <iostream>
#include <string>

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::ostream& os) const
	// {
	// 	os << mName << " " << mAge << std::endl;
	// };

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

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



int main()
{
	Cat kitty{"kitty",1};
	Cat nabi{"nabi", 2};

	std::cout << kitty << std::endl;
	std::cout << nabi << std::endl;
	// ==, < , <<

	// kitty.print(std::cout);
	// nabi.print(std::cout);
	return 0;

}

std::ostream& operator<<(std::ostream& os, const Cat& c)
{
return os<< c.name() <<" " << c.age();
};
을 보면 cout은 ostream의 종류 중 하나임을 알 수 있다.

std::ostream& operator<<(std::ostream& os, const Cat& c)
{
return os<< c.name() <<" " << c.age();
};
로 output stream을 만들고 만들었던 "<<"operator를 사용하면
std::cout << kitty << std::endl;

으로 출력된다.

이렇게 하면 output stream을 받는 flexible한 함수이고, 이런 함수는 OOP중심의 직관적인 output을 지원한다.

0개의 댓글