Operator Overloading

Course 1 · Ch 6
Operator Overloading
The mechanism every single cout statement since Chapter 1 has secretly been using all along

Every std::cout << ... line since cpp1-1 has quietly relied on a mechanism this chapter finally names directly.

Why Operator Overloading

A Vector2D class: adding two vectors should read naturally as v1 + v2, not add(v1, v2). C has no equivalent mechanism at all — every "operation" on a struct must be a plainly-named function call, always.

Overloading +

class Vector2D { public: double x, y; Vector2D operator+(const Vector2D &other) { return Vector2D{x + other.x, y + other.y}; } }; Vector2D v1{1, 2}, v2{3, 4}; Vector2D sum = v1 + v2; // reads naturally, calls operator+

Written as a member function, this supplies the left operand implicitly; other is the right one.

Overloading ==

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

Returns a genuine boolcpp1-2's own real boolean primitive, put to direct use.

Overloading << for Output

A real exception to the pattern so far: operator<< must be a free function, not a member — the left operand is std::ostream&, not the class itself, so it can't be written as a member of Vector2D. A friend declaration lets the free function reach the class's private members.

class Vector2D { private: double x, y; friend std::ostream& operator<<(std::ostream& os, const Vector2D &v); }; std::ostream& operator<<(std::ostream& os, const Vector2D &v) { os << "(" << v.x << ", " << v.y << ")"; return os; }

Which Operators Can/Can't Be Overloaded

Most can — arithmetic, comparison, stream, subscript [], function-call (), and more. A small, fixed set genuinely cannot: ::, ., .*, ?:, sizeof — a real exclusion list, not an arbitrary restriction.

The Real Payoff — This Is What cout << Already Uses

Here's the reveal: std::cout << 5 is itself a call to operator<<(ostream&, int) — an overload of exactly this same operator, just for a built-in type instead of a custom one. Every cout statement since Chapter 1 has been using this mechanism the entire time.

ConceptCC++
Custom "addition" for a typea plainly-named function — add(a, b)operator+ — a + b reads naturally
Left operand isn't the classn/a — no operator concept at allrequires a free function, not a member
Preserve the operator's natural meaning
Overload + for something genuinely addition-like — never for an unrelated operation just because the syntax happens to be convenient. A real style principle, sometimes called the principle of least astonishment.
operator<< can't be a member — a common beginner mistake
Attempting to write operator<< as a member function of the class itself is a genuine, common early confusion — the left-hand operand is ostream&, which isn't the class being extended, so member-function syntax simply doesn't fit.

Coding Challenges

Challenge 1

Write a Vector2D class with x and y members, overload operator+ as a member function, and print the sum of two vectors' x and y components after adding them.

📄 View solution
Challenge 2

Add operator== to the Vector2D class from Challenge 1, and test it against two vectors with identical components and two with different ones, printing the boolean result of each comparison.

📄 View solution
Challenge 3

Explain precisely why operator<< for a custom class cannot be written as a member function, tying your answer to which operand is on the left-hand side of the << expression.

📄 View solution

Chapter 6 Quick Reference

  • operator+/operator== — usually member functions, this as the implicit left operand
  • operator<< — must be a free function, since the left operand is ostream&, not the class
  • friend — lets a free function access a class's private members
  • A fixed, small set of operators genuinely cannot be overloaded — ::, ., .*, ?:, sizeof
  • std::cout << 5 already uses this exact mechanism — an operator<< overload for int
  • Next chapter: inheritance and polymorphism — making real the vtable mechanism c2-7 built by hand