Operation Overloading
C++에선 연산자를 호출할 때 a+b를 그대로진행하는 것이 아닌 a.operator+(b)와 같은 함수형식으로 연산을 진행한다.
즉, +, /, -, *, =, +=
과 같은 연산자는 함수오버로딩을 지원해, 클래스마다 연산방식을 제어 해 줄 수 있다.
Syntax
문법은 '반환형' operator'연산자'(피연산변수){ ... }
이다.
예를 들어 ‘+’ 연산자를 오버로딩 할 경우
class Test2 {
...
Test2 operator+(const Test2 &ref) {
Test2 t(Test2num + ref.Test2num);
return t;
}
}
위 처럼 class 내부에서 할 수 있으며, Test2형 클래스를 ‘+’ 연산을 할 경우 Test2::operator+( ... )
함수를 호출하게 된다.
또한 전역함수로 연산자 오버로딩을 할 경우 frind가 적절히 사용되는 몇 안되는 경중 하나인데,
friend Test2 operator+(const Test2 &ref, const Test2 &ref1);
...
Test2 operator+(const Test2 &ref, const Test2 &ref1) {
return ref.Test2num + ref2.Test2num;
}
Test2 클래스 끼리 + 연산을 할 때 내부 operator+함수가 아닌 전역 함수인 operator+( 피연산자1 , 피연사자2 )
를 호출하게 된다.
단항 연산자의 오버로딩
단항 연산자 또한 오버로딩이 가능하다.
다만, 특정 형태에 대해서 전역 함수형태로 오버로딩된 연산자는 동작이 다르게 되는데 이에 대해서도 알아보자.
class Optest { private: int num; public: Optest(int num) : num(num) {} void Show() { std::cout << num << " "; } Optest& operator++() { num += 1; return *this; } friend Optest& operator--(Optest &ref); }; Optest& operator--(Optest &ref) { ref.num -= 1; return ref; } int main(){ Optest op(10); ++op; op.Show(); --op; op.Show(); ++(++op); op.Show(); --(--op); op.Show(); return 0; }
++의 경우 return값이 *this 이다. 이를 연산하는 과정은
++(++op) > ++(op.operator++(10)) > ++ (op의 참조값); > (op의 참조값).operator++( )
위와 같이 진행된다. 계산이 완료되고 op의 참조값이 반환되면서 일반적인 ++ 연산이 가능한것이다.
–의 경우엔 return값이 ref 이다. 전달받은 잠조자를 return한다. 이를 연산하는 과정은
–(–op) > –(operator–(op)) >> –(op의 참조값) > operator(op의 참조값)
위처럼 진행된다.
전위 증가와 후위 증가
C++에선 전위 증가와 후위증가를 오버로딩 하기위해서, 키워드 int를 사용해 구분하고 있다.
++num은 operator++()
num++는 operator++(int)
교환 법칙의 구현
‘*’ 연산자의 경우엔 교환 법칙이 성립하는데 이를 기존의 operator* 하나론 교환 법칙이 성립되지 않게된다.
이를 해결하기 위해 operator*를 추가해 한번 더 오버로딩 해주면 된다.
class Optest { private: int num; public: Optest(int num) :num(num) {} int operator*(int num) { return this->num*num; } friend int operator*(int num, Optest& ref); }; int operator*(int num, Optest& ref) { return ref.num*num; } int main(){ Optest op(10); std::cout << 3*op << " " << op*3; return 0; }
++”<<“, “>>” 오버로딩
우리가 std::cout에 사용하는 “<<” 혹은 “>>”또한 연산자이기에 오버로딩이 가능하다.
즉, 클래스가 출력 혹인 입력을 받을 때에 일정하게 출력할 수 있다.
+++ [ ], new, delete, new[], delete[], () 오버로딩
각각의 사항들은 쓸 때 정리한다.