공부/C++

[C++] 10-3. 교환법칙 문제의 해결

knhoo 2024. 11. 27. 11:16
728x90
Point operator*(int times, Point& ref)
{
	Ponit pos(ref.xpos*times, ref.ypos*times);
    return pos;
}

자료형이 다른 두 피연산자를 대상으로 하는 연산

기본적으로 연산에 사용되는 두 피연산자의 자료형은 일치해야한다.

그리고 일치하지 않으면, 형 변환의 규칙에 따라서 변환이 진행된 다음에 연산이 이뤄져야 한다.

그러나 다음 예제에서 보이듯이 연산자 오버로딩을 이용하면, 이러한 연산 규칙에 예외를 둘 수 있다.

#include <iostream>
using namespace std;

class Point {
private:
	int xpos, ypos;
public:
	Point(int x = 0, int y = 0) : xpos(x), ypos(y)
	{ }
	void ShowPosition() const
	{
		cout << '[' << xpos << ", " << ypos << ']' << endl;
	}
	Point operator*(int times)
	{
		Point pos(xpos *times, ypos*times);
		return pos;
	}
};

int main(void) {
	Point pos(1, 2);
	Point cpy;

	cpy = pos * 3; //pos.operator*(3);
	cpy.ShowPosition();

	cpy = pos * 3 * 2;
	cpy.ShowPosition();
	return 0;
}

위 예제에서 오버로딩한 곱셈 연산자의 경우, Point 클래스의 멤버함수 형태로 정의했기 때문에

Point 객체가 * 연산자의 왼편에 와야 한다.

그러나 곱셈연산은 교환 법칙이 성립한다.

 

따라서 다음 두 문장이 동일한 결과를 보이도록 구현하는 것이 좋다.

  • cpy = pos * 3 ;
  • cpy = 3 * pos;

 

그러나 멤버함수의 형태로 오버로딩이 되면, 멤버함수가 정의된 클래스의 객체가 오버로딩 된 연산자의 왼편에 와야하기 때문에,

위 예제에서 오버로딩 한 형태로는 교환법칙이 성립되지 않는다.

 


교환법칙의 성립을 위한 구현

  • cpy = 3 * pos;

위 형태의 곱셈 연산이 가능하려면, 전역함수의 형태로 곱셈 연산자를 오버로딩 하는 수 밖에 없다.

즉, 위의 문장이 다음과 같이 해석되어야 한다.

  • cpy = operator*(3, pos);

이를 위해서는 opeator* 함수를 다음과 같이 정의해야 한다.

Point operator*(int times, Point& ref)
{
	Point pos(ref.xpos*times, ref,ypos*times);
    	return pos;
}

 

다음과 같이 '3*pos'를 'pos*3'이 되도록 바꾸는 형태로 오버로딩을 해도 된다.

Point operator*(int times, Point& ref) {
	return ref * times;
}
728x90