[C++/Syntax] 연산자 오버로딩

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[], () 오버로딩

각각의 사항들은 쓸 때 정리한다.

카테고리C++

글의 문제가 있다면 댓글을 달아 주세요.

This site uses Akismet to reduce spam. Learn how your comment data is processed.