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 ==, !=, <, >, <= et >= vous permettent de comparer des objets de vos classes personnalisées. Ces opérateurs renvoient un bool et doivent être marqués const, puisqu’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 les autres opérateurs de comparaison en fonction de ceux que vous avez déjà définis. Une fois que vous avez == et <, les autres suivent 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 du 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 « less-than », les autres opérateurs restent automatiquement synchronisés.
Défi
FacileConstruisons une classe Version qui représente des numéros de version logicielle (comme 2.1.0 ou 3.0.5) et prend en charge les six opérateurs de comparaison. Il s’agit d’un cas d’utilisation pratique où la comparaison des versions permet de déterminer quel logiciel est le plus récent, ce qui est 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 majeure, mineure et de correctif. Votre classe doit prendre en charge :- Un constructeur qui accepte les valeurs majeure, mineure et de correctif
- Des accesseurs 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 dans le format"major.minor.patch"
Implémentez directement
==et<, puis définissez les quatre opérateurs restants à partir de ces deux opérateurs. Pour la comparaison « inférieur à », comparez d’abord la version majeure, puis la version mineure si les versions majeures sont égales, et enfin le correctif si les versions majeure et mineure sont toutes deux égales. Tous les opérateurs de comparaison doivent être des fonctions membres const.main.cpp: lisez six entiers depuis 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 à l’aide de 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é consiste ici à implémenter les quatre opérateurs dérivés (!=, >, <=, >=) en utilisant uniquement == et <. Cela réduit la duplication du code et garantit la cohérence de tous les opérateurs si vous modifiez un jour 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 protections contre les inclusions multiples dans votre fichier d’en-tête.
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" (en 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 externesGénération et compilation en C++Fichiers d’en-tête et fichiers sourceEspaces de noms et portéeIntroduction à la POO en C++Classes et objetsLe pointeur « this »Méthodes (fonctions membres)Attributs (membres de données)Bases des constructeurs et destructeursRécapitulatif - Calculatrice simple4Propriétés de classe
Membres d’instance et statiquesAccesseurs et mutateursFonctions membres constMot-clé mutableMéthodes et variables statiquesFonctions et classes amiesRécapitulatif - Gestionnaire de compte bancaire7Héritage
Héritage de baseNiveaux d’accès de l’héritageOrdre d’appel des constructeurs et destructeursRedéfinition des méthodesFonctions virtuelles et VTableHéritage multipleHéritage virtuelRécapitulatif : hiérarchie des employés10Vue d’ensemble de la STL
Vue d’ensemble et philosophie de la STLConteneurs de la STLItérateursAlgorithmes de la STLFoncteurs et expressions lambdaRécapitulatif - fréquence des mots13Modèles de conception, partie 1
Introduction aux modèles de conceptionModèle SingletonFabrique et fabrique abstraiteModèle BuilderModèle ObserverModèle Strategy2Gestion de la mémoire
Mémoire de pile ou de tasPointeurs et référencesMémoire dynamique (new/delete)Pointeurs intelligents 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 de l’informationStruct vs classeClasses imbriquées et internesRécapitulatif - Système de gestion des dossiers étudiants8Polymorphisme
Polymorphisme à la compilation vs à l’exécutionSurcharge de fonctionsRetour sur les fonctions virtuellesFonctions virtuelles puresClasses abstraitesConception d’interfaces en C++Conversion dynamique et RTTIRécapitulatif - Calculateur de formes3Constructeurs et destructeurs
Constructeur par défautConstructeur paramétréConstructeur de copieConstructeur de déplacementListes d’initialisation des constructeursConstructeurs déléguésApprofondissement des destructeursRègle des trois / cinq / zéroRécapitulatif - Classe String6Surcharge des opérateurs
Introduction à la surcharge des 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 des templatesTemplates variadiquesBases de SFINAE et des traits de typesRécapitulatif - Conteneur génériqueEntraînez-vous par vous-même : Compilateur C++ en ligne