CppOperator Overloading

Operator Overloading

Operator overloading lets you define what operators like +, ==, or << mean for your own class types, so objects of that type can be combined and compared with the same natural syntax as built-in types like int or double.

Member vs. free function

An operator can be overloaded as a member function of the class, or as a free (non-member) function — sometimes declared a friend of the class so it can reach private data.

Situation

Which form to use

Left operand is always your class (e.g. a + b where a is your type)

Member function works well: a.operator+(b)

Left operand is not your class (e.g. std::cout << myObject)

Must be a free function — the left operand (std::cout) is not your type, so it cannot own the member function

Operator needs access to private data but isn't naturally a member

Free function declared friend inside the class

Note
`operator<<` for printing with `std::cout` is the classic example of why this distinction matters: `std::cout << obj` is really `operator<<(std::cout, obj)`. Since the left-hand operand is `std::ostream`, not your class, the operator **cannot** be a member of your class — it must be a free function (typically a `friend`).
A worked example: Vector2D

Overloading +, ==, and << for a 2D vector

CPP
#include <iostream>

class Vector2D {
public:
    double x, y;

    Vector2D(double x = 0, double y = 0) : x(x), y(y) {}

    // Member function: left operand is always a Vector2D, so this works well.
    Vector2D operator+(const Vector2D& other) const {
        return Vector2D(x + other.x, y + other.y);
    }

    bool operator==(const Vector2D& other) const {
        return x == other.x && y == other.y;
    }

    // Free function needs access to private data here, but x/y are public,
    // so no 'friend' declaration is required in this particular example.
    friend std::ostream& operator<<(std::ostream& out, const Vector2D& v);
};

// Free function: left operand is std::ostream, not Vector2D.
std::ostream& operator<<(std::ostream& out, const Vector2D& v) {
    out << "(" << v.x << ", " << v.y << ")";
    return out; // return the stream so calls can be chained: cout << a << b
}

int main() {
    Vector2D a(1, 2);
    Vector2D b(3, 4);

    Vector2D sum = a + b;          // uses operator+
    bool same = (a == b);          // uses operator==

    std::cout << "a = " << a << "\n";       // uses operator<<
    std::cout << "sum = " << sum << "\n";
    std::cout << "a == b? " << same << "\n";
}
Keep overloads intuitive
Warning
Only overload an operator when its meaning for your type matches what programmers already expect from that symbol. `operator+` should combine two things and return a new value — not, for instance, modify one of its operands, print something, or perform an unrelated side effect. Overloading `operator==` to do a partial comparison, or `operator+` to do subtraction as a “joke,” makes code that reads correctly but behaves in a way nobody would guess — one of the easiest ways to introduce hard-to-find bugs.
What's next
  • The friend declaration used for operator<< above is explained in full on the next page, Friend Functions & Classes.