기본자료형간의 연산은 기본적으로 가능하지만 사용자가 정의한 class형식의 객체의 경우 연산자로 연산이 불가능하다.
int num1 = 5; int num2 = 3; num1 + num2;
-> 가능
Simple obj1; Simple obj2; obj1 + obj2;
-> 불가능
따라서 객체 간의 연산을 문법적으로 지원하기 위해 연산자 오버로딩이 존재한다.
만약 객체 간 + 연산을 하려고 한다면
obj1 + obj2;
하지만 기본자료형에 의한 연산이 아니므로 다음과 같이 c++은 변환하여 판단한다.
obj1.operator+(obj2);
operator+라는 함수의 호출로 보기 때문에 이를 사전에 정의해놓으면 + 연산의 행동을 지정해줄 수 있다.
연산자 오버로딩은 2가지 선언방법이 있다.
- 멤버함수 형태
- 전역함수 형태
obj1.operator+(obj2);
같은 경우는 멤버함수의 경우이다.
전역함수의 경우 operator+(obj1, obj2)
의 형태가 된다.
class Point
{
private:
int xpos;
int ypos;
public:
Point(int x = 0, int y = 0) :xpos(x), ypos(y)
{ }
Point operator+(const Point& pos2)
{
Point pos(xpos + pos2.xpos, ypos + pos2.ypos);
return pos;
}
};
int main()
{
Point pos1(1,2);
Point pos2(3,4);
Point pos3 = pos1 + pos2;
멤버함수로 operator+를 정의해주고 + 연산시의 행동을 정의해주고 있다.
class Point
{
private:
int xpos;
int ypos;
public:
Point(int x = 0, int y = 0) :xpos(x), ypos(y)
{ }
friend Point operator+(const Point& pos2);
};
Point operator+(const Point& pos1, const Point& pos2)
{
Point pos(pos1.xpos + pos2.xpos, pos1.ypos + pos2.ypos);
return pos;
}
int main()
{
Point pos1(1,2);
Point pos2(3,4);
Point pos3 = pos1 + pos2;
friend 선언을 해야하므로 멤버함수로 선언하자.
위와 같은 연산자는 오버로딩이 불가하다.
위와 같이 원본 객체에 대한 참조가 필요한 경우는 멤버함수의 형태로만 오버로딩 가능
- 본래의 의도를 벗어난 연산자 오버로딩은 하지말자
- + 연산에 멤버간 * 연산을 하는 경우를 하지말자
- 연산자 우선순위와 결합성은 바뀌지 않는다.
- 매개변수의 디폴트 값 설정이 불가하다.
- 연산자의 순수 기능까지 뺏을 수 없다.
- 기본자료형의 연산까지 오버로딩 할 수 없다.