Lesson 5 · 5 of 20
Operator overloading · C++
Give your C++ classes their own operators (+, *, +=, ==, < and <<) with a Money type that stores cents, so sums never lose a penny.

Money keeps the amount in cents inside a long, because a double cannot represent values like 0.10 exactly. The constructor is `explicit`: it stops a stray number from silently turning into Money. euros() is a `static` method: you call it on the class, Money::euros(1.80), without an object, and it rounds to cents.
Overloading an operator means writing a function named operator+, operator* and so on. Then coffee * 2 + croissant reads like ordinary arithmetic: the compiler turns it into coffee.operator*(2).operator+(croissant). The arithmetic operators are const and return a new value; +=, on the other hand, changes the object itself and returns *this by reference, just like the standard library types do.
== and < return bool, so amounts can be compared, and thanks to < the type already works with std::sort or std::max. std::boolalpha makes cout print true and false instead of 1 and 0.
operator<< cannot be a member, because the stream goes on its left (std::cout << order). It is declared `friend` inside the class: a free function that is allowed to read cents_. It prints the euros, a dot and the cents as two digits (setw(2) and setfill('0'), which it then puts back) and returns the stream so more << can follow.
Code · main.cpp
#include <iomanip>#include <iostream>// Money kept in cents, so sums never suffer rounding errors.class Money { long cents_;public: explicit Money(long cents = 0) : cents_(cents) {} static Money euros(double e) { return Money(static_cast<long>(e * 100 + 0.5)); } // Arithmetic operators return a new value; += changes this one. Money operator+(const Money& o) const { return Money(cents_ + o.cents_); } Money operator*(int qty) const { return Money(cents_ * qty); } Money& operator+=(const Money& o) { cents_ += o.cents_; return *this; } bool operator==(const Money& o) const { return cents_ == o.cents_; } bool operator<(const Money& o) const { return cents_ < o.cents_; } // << is a free function (the stream goes on the left); friend lets it see cents_. friend std::ostream& operator<<(std::ostream& os, const Money& m) { return os << m.cents_ / 100 << '.' << std::setw(2) << std::setfill('0') << m.cents_ % 100 << std::setfill(' ') << " EUR"; }};int main() { Money coffee = Money::euros(1.80), croissant = Money::euros(2.25); Money order = coffee * 2 + croissant; std::cout << "Order: " << order << "\n"; Money till; for (int i = 0; i < 3; ++i) till += order; std::cout << "Till after 3 orders: " << till << "\n"; std::cout << std::boolalpha; std::cout << "Coffee < croissant? " << (coffee < croissant) << "\n"; std::cout << "Two coffees == 3.60? " << (coffee * 2 == Money::euros(3.60)) << "\n";}Output · c++ -std=c++17 main.cpp -o main && ./main
Order: 5.85 EUR Till after 3 orders: 17.55 EUR Coffee < croissant? true Two coffees == 3.60? true
Key points
operator+,operator==,operator<<… are functions with a special name.- Arithmetic operators return a new value; compound ones such as
+=return*this. explicitprevents implicit conversions from the constructor's argument type.operator<<is a free function (often afriend) that returns the stream.- Store money as whole numbers of cents, not as
double.
Exercise
Add operator- and use it to work out the change when a customer pays for the order with a 10-euro note. Check that the result is 4.15 EUR.