Sobrecarga de Operadores de Comparação
Parte da seção Programação Orientada a Objetos do Journey de C++ da Coddy. Lição 42 de 104.
operadores de comparação, como ==, !=, <, >, <= e >=, permitem comparar objetos das suas classes personalizadas. Esses operadores retornam um bool e devem ser marcados como const, pois não modificam nenhum dos operandos.
class Date {
int year, month, day;
public:
Date(int y, int m, int d) : year(y), month(m), day(d) {}
bool operator==(const Date& other) const {
return year == other.year &&
month == other.month &&
day == other.day;
}
bool operator<(const Date& other) const {
if (year != other.year) return year < other.year;
if (month != other.month) return month < other.month;
return day < other.day;
}
};Uma técnica útil é implementar outros operadores de comparação em termos daqueles que você já definiu. Assim que tiver == e <, os demais surgem naturalmente:
bool operator!=(const Date& other) const {
return !(*this == other);
}
bool operator>(const Date& other) const {
return other < *this;
}
bool operator<=(const Date& other) const {
return !(other < *this);
}
bool operator>=(const Date& other) const {
return !(*this < other);
}Essa abordagem reduz a duplicação de código e garante que todos os seus operadores de comparação se comportem de forma consistente. Se você alterar posteriormente o funcionamento da igualdade ou do operador menor que, os outros operadores permanecerão automaticamente sincronizados.
Desafio
FácilVamos criar uma classe Version que representa números de versão de software (como 2.1.0 ou 3.0.5) e oferece suporte a todos os seis operadores de comparação. Este é um caso de uso prático em que comparar versões determina qual software é mais recente, perfeito para praticar a sobrecarga de operadores de comparação.
Você criará dois arquivos para organizar seu código:
Version.h: Defina uma classeVersionque armazena três inteiros representando os números de versão major, minor e patch. Sua classe deve oferecer suporte a:- Um construtor que recebe valores major, minor e patch
- Getters para cada componente:
getMajor(),getMinor(),getPatch()(todos const) - Todos os seis operadores de comparação:
==,!=,<,>,<=,>= - Um método
toString()que retorna a versão como uma string no formato"major.minor.patch"
Implemente
==e<diretamente e, em seguida, defina os outros quatro operadores com base nesses dois. Para a comparação de menor que, compare primeiro major, depois minor se os valores major forem iguais e, por fim, patch se tanto major quanto minor forem iguais. Todos os operadores de comparação devem ser funções-membro const.main.cpp: Leia seis inteiros da entrada representando duas versões (major1, minor1, patch1, major2, minor2, patch2 em linhas separadas). Crie dois objetosVersione compare-os usando todos os seus operadores.Formato da saída:
Version 1: <v1> Version 2: <v2> v1 == v2: <true/false> v1 != v2: <true/false> v1 < v2: <true/false> v1 > v2: <true/false> v1 <= v2: <true/false> v1 >= v2: <true/false>Imprima
trueoufalse(em minúsculas) para cada resultado de comparação.
A técnica principal aqui é implementar os quatro operadores derivados (!=, >, <=, >=) usando apenas == e <. Isso reduz a duplicação de código e garante que todos os operadores permaneçam consistentes caso você altere a lógica de comparação.
Converta strings de entrada em inteiros usando std::stoi(). Use std::to_string() para criar a string da versão. Não se esqueça dos protetores de inclusão no arquivo de cabeçalho.
Experimente você mesmo
#include <iostream>
#include <string>
#include "Version.h"
using namespace std;
int main() {
// Ler seis inteiros para duas versões
string line;
getline(cin, line);
int major1 = stoi(line);
getline(cin, line);
int minor1 = stoi(line);
getline(cin, line);
int patch1 = stoi(line);
getline(cin, line);
int major2 = stoi(line);
getline(cin, line);
int minor2 = stoi(line);
getline(cin, line);
int patch2 = stoi(line);
// TODO: Crie dois objetos Version
// TODO: Exiba Version 1 e Version 2 usando toString()
// TODO: Compare usando todos os seis operadores e exiba os resultados
// Use "true" ou "false" (minúsculas) para cada comparação
// Formato: "v1 == v2: true" ou "v1 == v2: false"
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