Surcharge des opérateurs de comparaison
Fait partie de la section Programmation Orientée Objet du Journey C++ de Coddy — leçon 42 sur 104.
Les opérateurs de comparaison tels que ==, !=, <code><, , <= et >= vous permettent de comparer des objets de vos classes personnalisées. Ces opérateurs renvoient un bool et doivent être marqués const car ils ne modifient aucun des deux opérandes.
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;
}
};Une technique utile consiste à implémenter d'autres opérateurs de comparaison en fonction de ceux que vous avez déjà définis. Une fois que vous avez == et <code><, le reste suit naturellement :
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);
}Cette approche réduit la duplication de code et garantit que tous vos opérateurs de comparaison se comportent de manière cohérente. Si vous modifiez ultérieurement le fonctionnement de l'égalité ou de l'infériorité, les autres opérateurs restent automatiquement synchronisés.
Défi
FacileConstruisons une classe Version qui représente les numéros de version de logiciels (comme 2.1.0 ou 3.0.5) et qui prend en charge les six opérateurs de comparaison. Il s'agit d'un cas d'utilisation pratique où la comparaison des versions détermine quel logiciel est le plus récent — idéal pour s'exercer à la surcharge des opérateurs de comparaison.
Vous allez créer deux fichiers pour organiser votre code :
Version.h: Définissez une classeVersionqui stocke trois entiers représentant les numéros de version majeur, mineur et de correctif (patch). Votre classe doit prendre en charge :- Un constructeur qui prend les valeurs major, minor et patch
- Des accesseurs (getters) pour chaque composant :
getMajor(),getMinor(),getPatch()(tous const) - Les six opérateurs de comparaison :
==,!=,<,>,<=,>= - Une méthode
toString()qui renvoie la version sous forme de chaîne de caractères au format"major.minor.patch"
Implémentez
==et<directement, puis définissez les quatre opérateurs restants en fonction de ces deux-là. Pour la comparaison "inférieur à", comparez d'abord le majeur, puis le mineur si les majeurs sont égaux, puis le correctif si le majeur et le mineur sont tous deux égaux. Tous les opérateurs de comparaison doivent être des fonctions membres const.main.cpp: Lisez six entiers à partir de l'entrée représentant deux versions (major1, minor1, patch1, major2, minor2, patch2 sur des lignes séparées). Créez deux objetsVersionet comparez-les en utilisant tous vos opérateurs.Format de sortie :
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>Affichez
trueoufalse(en minuscules) pour chaque résultat de comparaison.
La technique clé ici consiste à implémenter les quatre opérateurs dérivés (!=, >, <=, >=) en utilisant uniquement == et <. Cela réduit la duplication de code et garantit que tous les opérateurs restent cohérents si jamais vous modifiez la logique de comparaison.
Convertissez les chaînes d'entrée en entiers à l'aide de std::stoi(). Utilisez std::to_string() pour construire la chaîne de version. N'oubliez pas les gardes d'inclusion (header guards) dans votre fichier d'en-tête.
Aide-mémoire
Les opérateurs de comparaison (==, !=, <code><, , <=, >=) vous permettent de comparer des objets de classes personnalisées. Ces opérateurs renvoient un bool et doivent être marqués const car ils ne modifient aucun des opérandes.
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;
}
};Implémentez les autres opérateurs de comparaison en fonction de == et <code>< pour réduire la duplication de code et garantir la cohérence :
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);
}Essayez vous-même
#include <iostream>
#include <string>
#include "Version.h"
using namespace std;
int main() {
// Lire six entiers pour deux 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: Créer deux objets Version
// TODO: Afficher Version 1 et Version 2 en utilisant toString()
// TODO: Comparer en utilisant les six opérateurs et afficher les résultats
// Utiliser "true" ou "false" (minuscules) pour chaque comparaison
// Format: "v1 == v2: true" ou "v1 == v2: false"
return 0;
}
Cette leçon comprend un petit quiz. Commencez la leçon pour y répondre et suivre votre progression.
Toutes les leçons de Programmation Orientée Objet
1Fondamentaux de la POO
Fichiers externesBuild et Compilation C++Fichiers d'en-tête et Fichiers sourceEspaces de noms et PortéeIntroduction à la POO en C++Classes vs ObjetsLe pointeur 'this'Méthodes (Fonctions membres)Attributs (Membres de données)Bases des Ctors et DtorsRécapitulatif - Calculatrice simple4Propriétés de classe
Membres d'instance vs membres statiquesGetters et SettersFonctions membres constMot-clé mutableMéthodes et variables statiquesFonctions et classes amiesRécapitulatif - Gestionnaire de compte bancaire7Héritage
Héritage de baseNiveaux d'accès à l'héritageOrdre d'appel des Ctor et DtorRedéfinition de méthodesFonctions virtuelles et VTableHéritage multipleHéritage virtuelRécapitulatif - Hiérarchie des employés10Présentation de la STL
Présentation et philosophie de la STLConteneurs de la STLItérateursAlgorithmes de la STLFoncteurs et expressions lambdaRécapitulatif - Fréquence des mots13Patrons de conception, Partie 1
Introduction aux patrons de conceptionPatron SingletonFabrique & Fabrique abstraitePatron MonteurPatron ObservateurPatron Stratégie2Gestion de la mémoire
Mémoire Pile vs TasPointeurs et RéférencesMémoire dynamique (new/delete)Smart Pointers en C++RAII en C++Récapitulatif - Gestionnaire de tableaux dynamiques5Encapsulation
Spécificateurs d'accès en C++Spécificateurs d'accès en profondeurMasquage d'informationStruct vs ClassClasses imbriquées et internesRécapitulatif - Système de gestion d'étudiants8Polymorphisme
Polymorphisme : Compilation vs ExécutionSurcharge de fonctionsRetour sur les fonctions virtuellesFonctions virtuelles puresClasses abstraitesConception d'interfaces en C++Dynamic Casting & RTTIRécapitulatif - Calculateur de formes11Concepts avancés de la POO
Composition vs HéritageMixins via CRTPIdiome PimplEffacement de typeEnum Classes & Typage fortGestion des exceptions en POOHiérarchies d'exceptions personnalisées14Patrons de conception, Partie 2
Patron CommandePatron AdaptateurPatron DécorateurPatron Template MethodPatron ÉtatPatron CompositeRAII en tant que patron3Constructeurs et Destructeurs
Constructeur par défautConstructeur paramétréConstructeur de copieConstructeur de déplacementListes d'initialisation du constructeurConstructeurs déléguésAnalyse approfondie du destructeurRègle de trois / cinq / zéroRécapitulatif - Classe String6Surcharge d'opérateurs
Introduction à la surcharge d'opérateursSurcharge des opérateurs arithmétiquesSurcharge des opérateurs de comparaisonOpérateurs de fluxSurcharge de l'opérateur d'affectationSurcharge des opérateurs [] et ()Opérateurs de conversion de typeRécapitulatif - Classe Matrix9Templates
Templates de fonctionsTemplates de classesSpécialisation de templatesTemplates variadiquesBases de SFINAE & Type TraitsRécapitulatif - Conteneur générique