Sovraccarico degli operatori di confronto
Fa parte della sezione Programmazione orientata agli oggetti del percorso C++ di Coddy. Lezione 42 di 104.
Gli operatori di confronto come ==, !=, <, >, <= e >= ti permettono di confrontare oggetti delle tue classi personalizzate. Questi operatori restituiscono un bool e dovrebbero essere contrassegnati come const, poiché non modificano nessuno dei due operandi.
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;
}
};Una tecnica utile consiste nell’implementare gli altri operatori di confronto basandosi su quelli che hai già definito. Una volta che hai == e <, gli altri seguono 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);
}Questo approccio riduce la duplicazione del codice e garantisce che tutti gli operatori di confronto si comportino in modo coerente. Se in seguito cambi il funzionamento dell'uguaglianza o dell'operatore minore di, gli altri operatori rimangono automaticamente sincronizzati.
Sfida
FacileCreiamo una classe Version che rappresenta i numeri di versione del software (come 2.1.0 o 3.0.5) e supporta tutti e sei gli operatori di confronto. Si tratta di un caso d’uso pratico in cui confrontare le versioni permette di determinare quale software è più recente, perfetto per esercitarsi con l’overload degli operatori di confronto.
Creerai due file per organizzare il codice:
Version.h: definisci una classeVersionche memorizza tre interi che rappresentano i numeri di versione major, minor e patch. La classe deve supportare:- Un costruttore che accetta i valori major, minor e patch
- Getter per ogni componente:
getMajor(),getMinor(),getPatch()(tutti const) - Tutti e sei gli operatori di confronto:
==,!=,<,>,<=,>= - Un metodo
toString()che restituisce la versione come stringa nel formato"major.minor.patch"
Implementa direttamente
==e<, poi definisci gli altri quattro operatori in funzione di questi due. Per il confronto minore di, confronta prima major, poi minor se i valori major sono uguali e infine patch se i valori major e minor sono entrambi uguali. Tutti gli operatori di confronto devono essere funzioni membro const.main.cpp: leggi sei interi dall’input che rappresentano due versioni (major1, minor1, patch1, major2, minor2, patch2 su righe separate). Crea due oggettiVersione confrontali usando tutti i tuoi operatori.Formato dell’output:
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>Stampa
trueofalse(in minuscolo) per ogni risultato del confronto.
La tecnica fondamentale consiste nell’implementare i quattro operatori derivati (!=, >, <=, >=) usando solo == e <. Questo riduce la duplicazione del codice e garantisce che tutti gli operatori rimangano coerenti se in futuro modifichi la logica di confronto.
Converti le stringhe di input in interi usando std::stoi(). Usa std::to_string() per creare la stringa della versione. Non dimenticare le protezioni contro le inclusioni multiple nel file header.
Provalo tu
#include <iostream>
#include <string>
#include "Version.h"
using namespace std;
int main() {
// Read six integers for two versions
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: Create two Version objects
// TODO: Output Version 1 and Version 2 using toString()
// TODO: Compare using all six operators and output results
// Use "true" or "false" (lowercase) for each comparison
// Format: "v1 == v2: true" or "v1 == v2: false"
return 0;
}
Questa lezione include un breve quiz. Inizia la lezione per rispondere e tenere traccia dei tuoi progressi.
Tutte le lezioni di Programmazione orientata agli oggetti
1Fondamenti della programmazione orientata agli oggetti
File esterniBuild e compilazione in C++File header e file sorgenteNamespace e ambitoIntroduzione alla programmazione orientata agli oggetti in C++Classi e oggetti a confrontoIl puntatore 'this'Metodi (funzioni membro)Attributi (membri dati)Fondamenti di costruttori e distruttoriRiepilogo - Calcolatrice semplice4Proprietà delle classi
Membri di istanza e staticiGetter e setterFunzioni membro constParola chiave mutableMetodi e variabili staticiFunzioni e classi friendRiepilogo - Gestore di conti bancari7Ereditarietà
Ereditarietà di baseLivelli di accesso nell’ereditarietàOrdine di chiamata di costruttori e distruttoriRidefinizione dei metodiFunzioni virtuali e VTableEreditarietà multiplaEreditarietà virtualeRiepilogo - Gerarchia dei dipendenti2Gestione della memoria
Memoria Stack vs HeapPuntatori e riferimentiMemoria dinamica (new/delete)Puntatori intelligenti in C++RAII in C++Riepilogo - Gestore di array dinamico5Incapsulamento
Specificatori di accesso in C++Specificatori di accesso in dettaglioOccultamento delle informazioniStruct vs classClassi annidate e interneRiepilogo - Sistema di registrazione degli studenti8Polimorfismo
Polimorfismo a compile time e a runtimeOverload delle funzioniFunzioni virtuali: ripassoFunzioni virtuali pureClassi astratteProgettazione delle interfacce in C++Dynamic casting e RTTIRipasso: calcolatrice di forme11Concetti avanzati di OOP
Composizione vs ereditarietàMixin tramite CRTPIdiom PimplType ErasureEnum class e tipizzazione forteGestione delle eccezioni in OOPGerarchie personalizzate di eccezioni14Pattern di progettazione - Parte 2
Pattern CommandPattern AdapterPattern DecoratorPattern Template MethodPattern StatePattern CompositeRAII come pattern3Costruttori e distruttori
Costruttore predefinitoCostruttore con parametriCostruttore di copiaCostruttore di spostamentoListe di inizializzazione dei costruttoriCostruttori delegantiApprofondimento sui distruttoriRegola del Tre / Cinque / ZeroRipasso - classe String6Sovraccarico degli operatori
Introduzione al sovraccarico degli operatoriSovraccarico degli operatori aritmeticiSovraccarico degli operatori di confrontoOperatori di flussoSovraccarico dell'operatore di assegnazioneSovraccarico degli operatori [] e ()Operatori di conversione di tipoRipasso - Classe Matrix9Template
Template di funzioneTemplate di classeSpecializzazione dei templateTemplate variadiciBasi di SFINAE e dei trait di tipoRiepilogo - Contenitore genericoEsercitati da solo: Compilatore C++ online