공부/C || C++

C++ 연산자 오버로딩(Operator overloading)

sudo 2021. 7. 22. 01:13

C++에서 연산자 오버로딩이란 C에서 정의하고 있는 연산자( +, -, /, *, ++, -- 등)의 동작을 다시 정의하는 것을 의미한다. 참고로 C언어는 연산자 오버로딩을 지원하지 않는다.

 

C언어에서 정의하고 있는 연산자의 동작이란 우리가 평소에 사용하는 것과 같다. 예를 들어 +, - 연산자들은 숫자에 대해서만 정의되어 있다. 하지만 C++에서는 연산자 오버로딩을 통해 클래스 객체끼리도 그런 연산들이 가능하게 해준다.

 

형태는 간단하게

반환타입 operator 연산자 ( <인자> )

방법은 2가지가 있다.

1. 멤버 함수에 의한 연산자 오버로딩

2. 전역 함수에 의한 연산자 오버로딩(클래스 정의에서 friend 선언 필요)

 

먼저 멤버 함수를 이용해서 연산자 오버로딩을 하는 경우를 보자

class Point
{
public:
	int x;
	int y;
	
	Point() {}
	Point(int x_, int y_) { x = x_; y = y_; }
	~Point() {}

	Point operator + (const Point& pt)
	{
		Point point;
		point.x = x + pt.x;
		point.y = y + pt.y;

		return point;
	}
};

int main()
{
	Point pt1(1, 2);
	Point pt2(3, 4);

	Point pt3 = pt1 + pt2;

	std::cout << "pt3.x: " << pt3.x << " pt3.y: " << pt3.y << std::endl;

	return 0;
}

위 코드처럼 + 연산자가 멤버함수로 오버로딩 되어있고, 컴파일러가 객체끼리 +를 만난다면 컴파일러는 pt1 + pt2를 만나면 pt1. operator+(pt2) 로 해석한다. 그래서 멤버 함수로 연산자 오버로딩 했을 때 특징이 인자가 하나라는 것이다.

 

전역 함수로 연산자 오버로딩을 해야하면 아래와 같이 써줘야 한다.

class Point
{
public:
	int x;
	int y;
	
	Point() {}
	Point(int x_, int y_) { x = x_; y = y_; }
	~Point() {}
};

Point operator + (const Point& pt1, const Point& pt2)
{
	Point pt(pt1.x + pt2.x, pt1.y + pt2.y);
	return pt;
}

int main()
{
	Point pt1(1, 2);
	Point pt2(3, 4);

	Point pt3 = pt1 + pt2;

	std::cout << "pt3.x: " << pt3.x << " pt3.y: " << pt3.y << std::endl;

	return 0;
}

다만 주의해줘야 할 점은 클래스 외부에서 선언된 만큼 접근해야 하는 멤버 변수들이 private로 선언되어 있다면 아래처럼 클래스 정의에서 전역함수를 friend로 선언해줘야 한다. 그래야 멤버 변수에 접근할 수 있기 때문이다.

class Point
{
private:
	int x;
	int y;

public:
	Point() {}
	Point(int x_, int y_) { x = x_; y = y_; }
	~Point() {}
	friend Point operator + (const Point& pt1, const Point& pt2);

	int GetX() { return x; }
	int GetY() { return y; }
};

Point operator + (const Point& pt1, const Point& pt2)
{
	Point pt(pt1.x + pt2.x, pt1.y + pt2.y);
	return pt;
}

int main()
{
	Point pt1(1, 2);
	Point pt2(3, 4);

	Point pt3 = pt1 + pt2;
    
	std::cout << "pt3.x: " << pt3.GetX() << " pt3.y: " << pt3.GetY() << std::endl;

	return 0;
}