기본 패턴
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";
}빠른 정리
| 항목 | 설명 |
|---|---|
| 목적 | 사용자 정의 타입의 사용성을 높임 |
| 의미 일관성 | 기존 연산자의 기대를 가능한 한 지키는 편이 좋음 |
| 멤버/비멤버 선택 | 좌우 대칭성과 접근 제약을 보고 결정 |
| 자주 오버로드되는 연산자 | +, ==, <<, [], () 등 |
| 과용 주의 | 문법 편의보다 직관과 유지보수성이 더 중요 |
주의할 점
연산자 오버로딩은 "멋있어 보여서" 추가하면 오히려 코드 의미를 숨길 수 있습니다. 기본 타입에서 기대하는 직관을 지킬 수 있을 때만 쓰는 편이 좋습니다.