C++함수와 클래스

연산자 오버로딩 기본

사용자 정의 타입을 더 자연스럽게 다루게 해 주는 연산자 오버로딩의 기본 원칙을 정리합니다.

마지막 수정 2026년 3월 19일

기본 패턴

cpp
struct Point {
    int x;
    int y;

    Point operator+(const Point& other) const {
        return {x + other.x, y + other.y};
    }
};

설명

  • 연산자 오버로딩은 사용자 정의 타입을 기본 타입처럼 더 자연스럽게 다루게 해 주는 기능입니다.
  • 핵심은 "편리함"보다 "기존 연산자의 의미를 얼마나 일관되게 유지하는가"입니다. +는 보통 새 값을 만들고, +=는 자기 자신을 바꾸는 식의 기대를 지키는 편이 좋습니다.
  • 멤버 함수로 구현할 수도 있고 비멤버 함수로 구현할 수도 있으며, 좌변/우변 대칭성이 중요한 연산자는 비멤버가 더 자연스러운 경우도 많습니다.
  • 스트림 출력 operator<<처럼 표준 라이브러리와 잘 어울리는 오버로드를 제공하면 디버깅과 사용성이 좋아집니다.
  • 반대로 억지로 의미를 비틀어 오버로딩하면 문법은 예뻐 보여도 코드를 읽는 사람이 직관을 잃기 쉽습니다.

짧은 예제

cpp
#include <iostream>

struct Point {
    int x;
    int y;

    Point operator+(const Point& other) const {
        return {x + other.x, y + other.y};
    }
};

int main() {
    Point a{1, 2};
    Point b{3, 4};
    Point c = a + b;
    std::cout << c.x << ", " << c.y << "\n";
}

빠른 정리

항목설명
목적사용자 정의 타입의 사용성을 높임
의미 일관성기존 연산자의 기대를 가능한 한 지키는 편이 좋음
멤버/비멤버 선택좌우 대칭성과 접근 제약을 보고 결정
자주 오버로드되는 연산자+, ==, <<, [], ()
과용 주의문법 편의보다 직관과 유지보수성이 더 중요

주의할 점

연산자 오버로딩은 "멋있어 보여서" 추가하면 오히려 코드 의미를 숨길 수 있습니다. 기본 타입에서 기대하는 직관을 지킬 수 있을 때만 쓰는 편이 좋습니다.