c++

C++ 연산자 오버로딩 사용법

개발에대해 2025. 9. 21. 09:41

 

C++ 연산자 오버로딩 사용법과 주의사항

 

C++에서는 기존 연산자(+,-,*,= 등)를 '사용자 정의 타입에 맞게 동작' 하도록 재정의할 수 있습니다.

이를 연산자 오버로딩(Operator Overloading)이라고 합니다.

 

연산자 오버로딩을 사용하면, 클래스 객체끼리도 직관적으로 연산이 가능해지고, 코드 가독성이 높아집니다.

하지만 잘못 구현하면 의도치 않은 동작이나 성능 문제를 발생시킬 수 있으므로 주의가 필요합니다.

 

1. 연산자 오버로딩 기본 문법

연산자 오버로딩은 클래스 안에서 operator연산자 형식으로 함수를 정의합니다.

예를 들어, 두 개의 Point 객체를 더하는 + 연산자를 오버로딩하려면 다음과 같이 작성합니다.


#include <iostream>
using namespace std;

class Point {
public:
    int x, y;

    Point(int _x=0, int _y=0) : x(_x), y(_y) {}

    // + 연산자 오버로딩
    Point operator+(const Point& p) const {
        return Point(x + p.x, y + p.y);
    }
};

int main() {
    Point p1(1,2), p2(3,4);
    Point p3 = p1 + p2; // Point::operator+ 호출
    cout << "(" << p3.x << "," << p3.y << ")" << endl; // 출력: (4,6)
}
  

 

2. 연산자 오버로딩 가능한 연산자

 

대부분의 연산자를 오버로딩할 수 있지만, '오버로딩할 수 없는 연산자' 도 있습니다.

  • 오버로딩 가능: +, -, *, /, %, =, +=, -=, ==, !=, <, >, <=, >=, [], (), ->, ++, -- 등
  • 오버로딩 불가: ::, ., .*, sizeof, typeid, sizeof..., ?:

 

3. 연산자 오버로딩 구현 예제

 

다음은 Complex 클래스에서 +와 == 연산자를 오버로딩한 예제입니다.


#include <iostream>
using namespace std;

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

    // + 연산자
    Complex operator+(const Complex& c) const {
        return Complex(real + c.real, imag + c.imag);
    }

    // == 연산자
    bool operator==(const Complex& c) const {
        return real == c.real && imag == c.imag;
    }
};

int main() {
    Complex c1(1,2), c2(3,4);
    Complex c3 = c1 + c2;

    if(c3 == Complex(4,6))
        cout << "같음" << endl;
}
  

 

4. 주의사항

연산자 오버로딩은 편리하지만, 잘못 사용하면 코드 가독성과 유지보수성을 해칠 수 있습니다.

  • 직관적이지 않은 오버로딩 금지: 연산자의 의미와 맞지 않는 동작은 피해야 합니다. 예: + 연산자로 데이터를 삭제하는 행위
  • 복사 비용 주의: 큰 객체를 값으로 반환하면 성능 저하 가능 → 참조 반환이나 move semantics 고려
  • 대입 연산자 = 오버로딩 시 self-assignment 방지: this와 rhs가 같은 객체인지 확인 필요
  • 연산자 우선순위와 결합 규칙 유지: 기존 연산자 우선순위를 벗어나면 혼란 발생
  • 기본 타입과 혼합 연산: 사용자 정의 타입과 int, double 등을 같이 연산하려면 non-member 함수로 오버로딩 필요
 

5. 정리

C++ 연산자 오버로딩은 사용자 정의 타입에서도 직관적인 연산을 가능하게 하며, 코드 가독성을 높여줍니다.

그러나 의미와 맞지 않거나, 복사 비용이 큰 오버로딩은 성능과 유지보수성을 저하시킬 수 있습니다.

따라서 연산자 오버로딩은 필요할 때만, 직관적이고 안전하게 사용하는 것이 중요합니다.

반응형