Lección 5 · 5 de 20
Sobrecarga de operadores · C++
Dé a sus clases de C++ operadores propios (+, *, +=, ==, < y <<) con un tipo Money que guarda céntimos para no perder ni un euro al sumar.

Money guarda el dinero en céntimos dentro de un long, porque un double no representa exactamente valores como 0,10. El constructor es `explicit`: impide que un número suelto se convierta en Money sin querer. euros() es un método `static`: se llama sobre la clase, Money::euros(1.80), sin necesitar un objeto, y redondea a céntimos.
Sobrecargar un operador es escribir una función llamada operator+, operator*, etc. Así coffee * 2 + croissant se lee como una cuenta normal: el compilador la convierte en coffee.operator*(2).operator+(croissant). Los operadores aritméticos son const y devuelven un valor nuevo; +=, en cambio, cambia el propio objeto y devuelve *this por referencia, como hacen los tipos de la biblioteca estándar.
== y < devuelven bool, de modo que los importes se pueden comparar, y gracias a < el tipo ya sirve para std::sort o std::max. std::boolalpha hace que cout escriba true y false en vez de 1 y 0.
operator<< no puede ser miembro, porque a su izquierda va el flujo (std::cout << order). Se declara `friend` dentro de la clase: es una función libre, pero con permiso para leer cents_. Escribe los euros, un punto y los céntimos con dos cifras (setw(2) y setfill('0'), que luego se deja como estaba) y devuelve el flujo para poder encadenar más <<.
Código · 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";}Salida · 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
Para recordar
operator+,operator==,operator<<… son funciones con un nombre especial.- Los operadores aritméticos devuelven un valor nuevo; los compuestos, como
+=, devuelven*this. explicitevita conversiones implícitas desde el tipo del constructor.operator<<es una función libre (a menudofriend) que devuelve el flujo.- Guarde el dinero en enteros (céntimos), no en
double.
Ejercicio
Añada operator- y úselo para calcular el cambio cuando un cliente paga el pedido con un billete de 10 euros. Compruebe que el resultado es 4.15 EUR.