Menu
Coddy logo textTech

Sobrecarga de Operadores Aritméticos

Parte da seção Programação Orientada a Objetos do Journey de C++ da Coddy — lição 41 de 104.

Operadores aritméticos como +, -, * e / são comumente sobrecarregados para fazer com que classes personalizadas se comportem como tipos numéricos integrados. Esses operadores normalmente retornam um novo objeto em vez de modificar os operandos.

Aqui está uma classe Fraction com 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 os operadores estão marcados como const, já que eles não modificam nenhum dos operandos. Eles criam e retornam um novo Fraction com o resultado.

Para operadores de atribuição composta como +=, o padrão difere. Estes modificam o operando à esquerda e retornam uma referência a ele:

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

Uma prática comum é implementar o operador básico em termos da atribuição composta, reduzindo a duplicação de código:

Fraction operator+(const Fraction& other) const {
    Fraction result = *this;    // Copia este objeto
    result += other;            // Usa atribuição composta
    return result;
}

Esta abordagem garante que ambos os operadores permaneçam consistentes e torna a manutenção mais fácil.

challenge icon

Desafio

Fácil

Vamos construir uma classe Money que lida com cálculos de moeda usando sobrecarga de operadores aritméticos. Você implementará múltiplos operadores aritméticos que permitem trabalhar com valores monetários de forma tão natural quanto faria com números comuns.

Você criará dois arquivos para organizar seu código:

  • Money.h: Defina uma classe Money que armazena um valor em centavos (como um int) para evitar problemas de precisão de ponto flutuante. Sua classe deve suportar:
    • Um construtor que recebe dólares e centavos como inteiros separados
    • Um getter getDollars() que retorna a parte dos dólares
    • Um getter getCents() que retorna a parte dos centavos (0-99)
    • Operadores + e - sobrecarregados que retornam um novo objeto Money
    • Operadores de atribuição composta += e -= sobrecarregados que modificam o objeto atual e retornam uma referência a ele
    • Um método display() que imprime o dinheiro no formato $X.YY (sempre dois dígitos para os centavos)

    Implemente os operadores básicos (+ e -) em termos dos operadores de atribuição composta para reduzir a duplicação de código, conforme mostrado na lição. Todos os operadores aritméticos devem ser marcados como const onde apropriado.

  • main.cpp: Leia quatro inteiros da entrada representando dois valores monetários (dollars1, cents1, dollars2, cents2 em linhas separadas). Crie dois objetos Money e, em seguida, demonstre todos os seus operadores:
    • Imprima "Amount 1: " seguido pelo primeiro valor exibido
    • Imprima "Amount 2: " seguido pelo segundo valor exibido
    • Some os dois valores e imprima "Sum: " seguido pelo resultado
    • Subtraia o segundo do primeiro e imprima "Difference: " seguido pelo resultado
    • Use += para adicionar o segundo valor ao primeiro e, em seguida, imprima "After +=: " seguido pelo primeiro valor modificado

Para o método display(), use std::setw(2) e std::setfill('0') de <iomanip> para garantir que os centavos sempre mostrem dois dígitos (por exemplo, $5.07 e não $5.7).

Converta as strings de entrada em inteiros usando std::stoi(). Não se esqueça dos "header guards" em seu arquivo de cabeçalho.

Folha de consulta

Operadores aritméticos como +, -, * e / podem ser sobrecarregados para fazer com que classes personalizadas se comportem como tipos numéricos integrados. Esses operadores normalmente retornam um novo objeto em vez de modificar os operandos.

Operadores aritméticos básicos devem ser marcados como const, pois não modificam nenhum dos operandos:

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

Operadores de atribuição composta como += e -= modificam o operando à esquerda e retornam uma referência a ele:

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

Uma prática comum é implementar operadores básicos em termos de operadores de atribuição composta para reduzir a duplicação de código:

Fraction operator+(const Fraction& other) const {
    Fraction result = *this;    // Copiar este objeto
    result += other;            // Usar atribuição composta
    return result;
}

Experimente você mesmo

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

using namespace std;

int main() {
    // Lê a entrada para dois valores monetários
    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: Criar dois objetos Money com os valores de entrada
    
    // TODO: Imprimir "Amount 1: " seguido pelo primeiro valor exibido
    
    // TODO: Imprimir "Amount 2: " seguido pelo segundo valor exibido
    
    // TODO: Somar os dois valores e imprimir "Sum: " seguido pelo resultado
    
    // TODO: Subtrair o segundo do primeiro e imprimir "Difference: " seguido pelo resultado
    
    // TODO: Usar += para adicionar o segundo valor ao primeiro, então imprimir "After +=: " seguido pelo primeiro valor modificado
    
    return 0;
}
quiz iconTeste seus conhecimentos

Esta lição inclui um quiz rápido. Comece a lição para respondê-lo e acompanhar seu progresso.

Todas as lições de Programação Orientada a Objetos