Menu
Coddy logo textTech

Sobrecarga de operadores aritméticos

Parte de la sección Programación Orientada a Objetos del Journey de C++ de Coddy — lección 41 de 104.

Los operadores aritméticos como +, -, * y / se sobrecargan comúnmente para que las clases personalizadas se comporten como tipos numéricos integrados. Estos operadores suelen devolver un nuevo objeto en lugar de modificar los operandos.

Aquí tienes una clase Fraction con operadores aritméticos:

class Fraction {
    int numerator, denominator;
    
public:
    Fraction(int n, int d) : numerator(n), denominator(d) {}
    
    Fraction operator+(const Fraction& other) const {
        return Fraction(
            numerator * other.denominator + other.numerator * denominator,
            denominator * other.denominator
        );
    }
    
    Fraction operator*(const Fraction& other) const {
        return Fraction(numerator * other.numerator, 
                        denominator * other.denominator);
    }
};

Observe que ambos operadores están marcados como const ya que no modifican ninguno de los operandos. Crean y devuelven una nueva Fraction con el resultado.

Para los operadores de asignación compuesta como +=, el patrón difiere. Estos modifican el operando izquierdo y devuelven una referencia al mismo:

Fraction& operator+=(const Fraction& other) {
    numerator = numerator * other.denominator + other.numerator * denominator;
    denominator = denominator * other.denominator;
    return *this;
}

Una práctica común es implementar el operador básico en términos de la asignación compuesta, reduciendo la duplicación de código:

Fraction operator+(const Fraction& other) const {
    Fraction result = *this;    // Copiar este objeto
    result += other;            // Usar la asignación compuesta
    return result;
}

Este enfoque garantiza que ambos operadores se mantengan consistentes y facilita el mantenimiento.

challenge icon

Desafío

Fácil

Vamos a construir una clase Money que maneje cálculos de moneda utilizando la sobrecarga de operadores aritméticos. Implementarás múltiples operadores aritméticos que te permitirán trabajar con valores monetarios de forma tan natural como lo harías con números normales.

Crearás dos archivos para organizar tu código:

  • Money.h: Define una clase Money que almacene una cantidad en centavos (como un int) para evitar problemas de precisión de punto flotante. Tu clase debe admitir:
    • Un constructor que reciba dólares y centavos como enteros separados
    • Un getter getDollars() que devuelva la parte de los dólares
    • Un getter getCents() que devuelva la parte de los centavos (0-99)
    • Operadores + y - sobrecargados que devuelvan un nuevo objeto Money
    • Operadores de asignación compuesta += y -= sobrecargados que modifiquen el objeto actual y devuelvan una referencia a él
    • Un método display() que imprima el dinero en el formato $X.YY (siempre dos dígitos para los centavos)

    Implementa los operadores básicos (+ y -) en términos de los operadores de asignación compuesta para reducir la duplicación de código, como se muestra en la lección. Todos los operadores aritméticos deben marcarse como const cuando sea apropiado.

  • main.cpp: Lee cuatro enteros de la entrada que representan dos cantidades de dinero (dollars1, cents1, dollars2, cents2 en líneas separadas). Crea dos objetos Money, luego demuestra todos tus operadores:
    • Imprime "Amount 1: " seguido de la primera cantidad mostrada
    • Imprime "Amount 2: " seguido de la segunda cantidad mostrada
    • Suma las dos cantidades e imprime "Sum: " seguido del resultado
    • Resta la segunda de la primera e imprime "Difference: " seguido del resultado
    • Usa += para sumar la segunda cantidad a la primera, luego imprime "After +=: " seguido de la primera cantidad modificada

Para el método display(), utiliza std::setw(2) y std::setfill('0') de <iomanip> para asegurar que los centavos siempre muestren dos dígitos (por ejemplo, $5.07 no $5.7).

Convierte las cadenas de entrada a enteros usando std::stoi(). No olvides los protectores de inclusión (header guards) en tu archivo de cabecera.

Hoja de referencia

Los operadores aritméticos como +, -, * y / pueden sobrecargarse para que las clases personalizadas se comporten como tipos numéricos integrados. Estos operadores suelen devolver un nuevo objeto en lugar de modificar los operandos.

Los operadores aritméticos básicos deben marcarse como const ya que no modifican ninguno de los operandos:

Fraction operator+(const Fraction& other) const {
    return Fraction(
        numerator * other.denominator + other.numerator * denominator,
        denominator * other.denominator
    );
}

Los operadores de asignación compuesta como += y -= modifican el operando de la izquierda y devuelven una referencia a él:

Fraction& operator+=(const Fraction& other) {
    numerator = numerator * other.denominator + other.numerator * denominator;
    denominator = denominator * other.denominator;
    return *this;
}

Una práctica común es implementar los operadores básicos en términos de los operadores de asignación compuesta para reducir la duplicación de código:

Fraction operator+(const Fraction& other) const {
    Fraction result = *this;    // Copiar este objeto
    result += other;            // Usar asignación compuesta
    return result;
}

Pruébalo tú mismo

#include <iostream>
#include <string>
#include "Money.h"

using namespace std;

int main() {
    // Leer la entrada para dos cantidades de dinero
    string line;
    
    getline(cin, line);
    int dollars1 = stoi(line);
    
    getline(cin, line);
    int cents1 = stoi(line);
    
    getline(cin, line);
    int dollars2 = stoi(line);
    
    getline(cin, line);
    int cents2 = stoi(line);
    
    // TODO: Crear dos objetos Money con los valores de entrada
    
    // TODO: Imprimir "Amount 1: " seguido de la primera cantidad mostrada
    
    // TODO: Imprimir "Amount 2: " seguido de la segunda cantidad mostrada
    
    // TODO: Sumar las dos cantidades e imprimir "Sum: " seguido del resultado
    
    // TODO: Restar la segunda de la primera e imprimir "Difference: " seguido del resultado
    
    // TODO: Usar += para sumar la segunda cantidad a la primera, luego imprimir "After +=: " seguido de la primera cantidad modificada
    
    return 0;
}
quiz iconPonte a prueba

Esta lección incluye un breve cuestionario. Empieza la lección para responderlo y registrar tu progreso.

Todas las lecciones de Programación Orientada a Objetos