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 / geralmente são 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 são marcados como const, pois não modificam nenhum dos operandos. Eles criam e retornam uma nova Fraction com o resultado.
Para operadores de atribuição composta como +=, o padrão é diferente. Eles 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 com base na 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 a atribuição composta
return result;
}Essa abordagem garante que ambos os operadores permaneçam consistentes e facilita a manutenção.
Desafio
FácilVamos criar uma classe Money que lida com cálculos monetários usando sobrecarga de operadores aritméticos. Você implementará vários operadores aritméticos que permitirão trabalhar com valores monetários tão naturalmente quanto com números comuns.
Você criará dois arquivos para organizar seu código:
Money.h: Defina uma classeMoneyque armazene um valor em centavos (como umint) para evitar problemas de precisão de ponto flutuante. Sua classe deve oferecer suporte a:- Um construtor que receba dólares e centavos como inteiros separados
- Um getter
getDollars()que retorne a parte em dólares - Um getter
getCents()que retorne a parte em centavos (0-99) - Operadores
+e-sobrecarregados que retornem um novo objetoMoney - Operadores de atribuição composta
+=e-=sobrecarregados que modifiquem o objeto atual e retornem uma referência a ele - Um método
display()que exiba o valor monetário no formato$X.YY(sempre com dois dígitos para os centavos)
Implemente os operadores básicos (
+e-) usando os 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 comoconstquando apropriado.main.cpp: Leia quatro inteiros da entrada representando dois valores monetários (dollars1, cents1, dollars2, cents2 em linhas separadas). Crie dois objetosMoneye, em seguida, demonstre todos os seus operadores:- Imprima
"Amount 1: "seguido do primeiro valor exibido - Imprima
"Amount 2: "seguido do segundo valor exibido - Some os dois valores e imprima
"Sum: "seguido do resultado - Subtraia o segundo do primeiro e imprima
"Difference: "seguido do resultado - Use
+=para adicionar o segundo valor ao primeiro e, em seguida, imprima"After +=: "seguido do primeiro valor modificado
- Imprima
Para o método display(), use std::setw(2) e std::setfill('0') de <iomanip> para garantir que os centavos sempre sejam exibidos com 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 das proteções de inclusão no arquivo de cabeçalho.
Experimente você mesmo
#include <iostream>
#include <string>
#include "Money.h"
using namespace std;
int main() {
// Ler a entrada para duas quantias de dinheiro
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 pela primeira quantia exibida
// TODO: Imprimir "Amount 2: " seguido pela segunda quantia exibida
// TODO: Somar as duas quantias e imprimir "Sum: " seguido pelo resultado
// TODO: Subtrair a segunda da primeira e imprimir "Difference: " seguido pelo resultado
// TODO: Usar += para adicionar a segunda quantia à primeira e então imprimir "After +=: " seguido pela primeira quantia modificada
return 0;
}
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
1Fundamentos de POO
Arquivos externosBuild e compilação em C++Arquivos de cabeçalho e arquivos-fonteNamespaces e escopoIntrodução à POO em C++Classes vs. objetosO ponteiro 'this'Métodos (funções membro)Atributos (membros de dados)Noções básicas de construtores e destruidoresRevisão - calculadora simples4Propriedades de Classe
Membros de Instância vs. EstáticosGetters e SettersFunções Membro ConstPalavra-chave MutableMétodos e Variáveis EstáticosFunções e Classes FriendRevisão - Gerenciador de Contas Bancárias7Herança
Herança básicaNíveis de acesso da herançaOrdem de chamada de construtor e destrutorSobrescrita de métodosFunções virtuais e VTableHerança múltiplaHerança virtualRevisão - Hierarquia de funcionários10Visão geral da STL
Visão geral e filosofia da STLContêineres da STLIteradoresAlgoritmos da STLFunctors e expressões lambdaRecapitulação - Frequência de palavras13Padrões de Projeto — Parte 1
Introdução aos Padrões de ProjetoPadrão SingletonFactory e Abstract FactoryPadrão BuilderPadrão ObserverPadrão Strategy2Gerenciamento de Memória
Memória Stack vs. HeapPonteiros e ReferênciasMemória Dinâmica (new/delete)Ponteiros Inteligentes em C++RAII em C++Revisão - Gerenciador de Array Dinâmico5Encapsulamento
Especificadores de acesso em C++Especificadores de acesso em profundidadeOcultação de informaçõesStruct vs ClasseClasses aninhadas e internasRecapitulação - Sistema de registros de alunos8Polimorfismo
Polimorfismo em compilação vs. execuçãoSobrecarga de funçõesFunções virtuais revisadasFunções virtuais purasClasses abstratasDesign de interfaces em C++Conversão dinâmica e RTTIRecapitulação — Calculadora de formas11Conceitos Avançados de OOP
Composição vs. HerançaMixins via CRTPIdioma PimplApagamento de TiposClasses Enum e Tipagem ForteTratamento de Exceções em OOPHierarquias de Exceções Personalizadas14Padrões de Projeto — Parte 2
Padrão CommandPadrão AdapterPadrão DecoratorPadrão Template MethodPadrão StatePadrão CompositeRAII como Padrão3Construtores e Destrutores
Construtor PadrãoConstrutor ParametrizadoConstrutor de CópiaConstrutor de MovimentoListas de Inicialização do ConstrutorConstrutores DelegantesAprofundamento em DestrutoresRegra dos Três / Cinco / ZeroRevisão - Classe String6Sobrecarga de Operadores
Introdução à Sobrecarga de OperadoresSobrecarga de Operadores AritméticosSobrecarga de Operadores de ComparaçãoOperadores de FluxoSobrecarga do Operador de AtribuiçãoSobrecarga dos Operadores [] e ()Operadores de Conversão de TipoRecapitulação - Classe Matrix9Templates
Templates de FunçõesTemplates de ClassesEspecialização de TemplatesTemplates VariádicosNoções Básicas de SFINAE e Traits de TiposRecapitulação - Contêiner GenéricoPratique por conta própria: Compilador de C++ online