Operators

연산자 오버로딩: 문법을 빌리는 설계 계약

operator+처럼 익숙한 기호를 쓰면 호출자는 기존 의미를 기대한다. 대칭성, 부작용, 변환 규칙이 그 기대와 맞아야 읽기 쉬운 코드가 된다.

01

기호 의미 확인

수학적 또는 표준 라이브러리 관례와 맞지 않는 연산자는 이름 있는 함수가 낫다.

02

멤버와 비멤버 선택

왼쪽 피연산자가 내 타입이어야 하는 연산은 멤버로, 대칭 변환이 필요하면 비멤버를 고려한다.

03

복합 연산을 기준으로 둔다

+=를 먼저 구현하고 +는 복사 후 +=를 호출하면 의미가 맞기 쉽다.

operator+
새 값을 만든다 왼쪽 객체를 바꾸면 호출자 기대를 깨기 쉽다.
변경은 +=에 둔다.
operator==
동등성 기준 모든 관찰 가능한 상태를 비교할지 식별자만 비교할지 정해야 한다.
정렬 기준과 혼동하지 않는다.
operator<
엄격 약순서 std::set, sort가 요구하는 비교 규칙을 만족해야 한다.
C++20은 <=>도 후보가 된다.
stream
비멤버가 자연스럽다 std::ostream이 왼쪽 피연산자라 멤버로 넣을 수 없다.
friend는 필요한 범위만 연다.

관례 · const · 비교 점검

관례 기호의 일반 의미와 다르면 함수 이름으로 드러내는 편이 안전한가.
const 비변경 연산자가 const 객체에서도 호출 가능한가.
비교 ==와 정렬 비교가 서로 모순된 결과를 만들지 않는가.

+=에서 + 만들기

class Vec2 {
public:
    Vec2& operator+=(const Vec2& rhs) { x += rhs.x; y += rhs.y; return *this; }
    friend Vec2 operator+(Vec2 lhs, const Vec2& rhs) { return lhs += rhs; }
private:
    int x = 0, y = 0;
};