본문 바로가기

C++

[C++] 연산자 오버로딩의 개념, 활용, 주의점

 

0. 연산자 오버로딩의 개념

  • 연산자 오버로딩은 C++에서의 특이하고도 강점인 기법이다.
  • 기본적으로 제공되는 연산자의 연산을 사용자가 직접 오버로딩하여 새로운 기능으로 정의할 수 있다.
  • ex) +연산자는 숫자를 더하는 1+2지만, 연산자 오버로딩을 통해  "C++" + "Program"과 같은 두 개의 문자열을 합친다.

 

 

1. 연산자 오버로딩의 사용 방법

  • 연산자 함수를 이용해서 구현한다.
  • operator op;  (op는 +,-,*와 같은 실제 연산자를 나타낸다.)

 

 

2. 연산자 오버로딩 + 예제

#include <iostream>
using namespace std;

class Point {

private:
	int m_x;
	int m_y;
	
public:
	Point(int x, int y) :m_x(x), m_y(y) {}
	Point operator+(const Point& p); //연산자 오버로딩
	void ShowPoint();

};

Point Point::operator+(const Point& p) { //연산자 오버로딩 구현
	return Point(m_x + p.m_x, m_y + p.m_y); 
}

void Point::ShowPoint() {
	cout << m_x << " " << m_y << endl;
}

void main() {
	Point p1(20, 10);
	Point p2(10, 20);
	Point a = p1 + p2;   //연산자 오버로딩 
	cout << "연산자 오버로딩 결과 : "; //결과는 30 30
	a.ShowPoint();

}

이 예제는 Point 클래스의 p1과 p2객체의 각각 두 인수를 더하는 예제이다.

main 함수에서 Point a = p1 + p2를 보면, 연산자 오버로딩이 적용되고 있다.

p2의 m.x, m.y를 operator+(const Point& p)에서 p.m_x, p.m_y로 접근하여 값을 가져온뒤, 더해주고 있는 모습이다.

 그리고 결과값을 Point 형식으로 반환한다.

 

 

 

3. 관계 연산자 오버로딩 (=> <)

#include <iostream>
using namespace std;

class Point {

private:
	int m_x;
	int m_y;
	
public:
	Point(int x, int y) :m_x(x), m_y(y) {}
	bool operator == (const Point& p);
	bool operator > (const Point& p);
	bool operator < (const Point& p);

};

bool Point::operator==(const Point& p) { //연산자 오버로딩 구현
	
	if (m_x == p.m_x && m_y == p.m_y)
		return true;
	else
		return false;
}

bool Point::operator>(const Point& p)
{
	if (m_x > p.m_x)
		return true;
	else if (m_y > p.m_y)
		return true;
	return false;
}

bool Point::operator<(const Point& p)
{
	if (m_x < p.m_x)
		return true;
	else if (m_y < p.m_y)
		return true;
	return false;
}



void main() {
	Point p1(10, 10);
	Point p2(10, 10);
	
	if (p1 > p2)
		cout << "p1이 p2보다 크다" << endl;
	else if (p1 < p2)
		cout << "p1이 p2보다 작다" << endl;
	else if (p1 == p2)
		cout << "p1은 p2와 같다" << endl;
}

코드가 길어보지만 막상 들여다보면 =, >, <의 오버로딩으로 인해 코드가 길어 보일 뿐 형식은 위와 똑같다.

두 객체의 멤버변수를 각각 비교하여, 두 멤버 변수가 같다면 TRUE을 리턴하고,

>, <의 경우는 x를 먼저 비교하고, 만약 x가 같다면 y값을 비교하여 대소를 판별한다.

 

 

 

4. 연산자 오버로딩을 통한 복소수 구현

#include<iostream>
using namespace std;

class Complex {
private:
    int real, imag;
public:
    Complex(int r = 0, int i = 0) { real = r;   imag = i; }

    Complex operator + (Complex const& obj) {
        Complex res;
        res.real = real + obj.real;
        res.imag = imag + obj.imag;
        return res;
    }
    void print() { cout << real << " + i" << imag << '\n'; }
};

int main()
{
    Complex c1(10, 5), c2(2, 4);
    Complex c3 = c1 + c2;
    c3.print(); //실행결과 12 + i9
}

 

 

 

5. 연산자 오버로딩 시 주의할 점

  •  기존에 존재하지 않은 연산자는 정의할 수 없다.
  • 연산자의 피연산자 수는 변경할 수 없다.
  • 연산자의 우선순위와 결합 방향은 변경할 수 없다.
  • 기본 데이터형에 대해서는 연산자를 오버로딩 할 수 없다.
  • :: . , * ? : sizeof 연산자는 오버로딩 할 수 없다.
  • = () [] -> 연산자를 오버로딩 할 시 연산자 함수는 멤버 함수로 구현된다.

 

 

 

 

 

참고자료

C++ 프로그래밍과 STL / 이창현 지음

https://www.geeksforgeeks.org/operator-overloading-c/