Vergleichsoperatorüberladung
Teil des Abschnitts Objektorientierte Programmierung der C++-Journey von Coddy. Lektion 42 von 104.
Vergleichsoperatoren wie ==, !=, <, >, <= und >= ermöglichen es dir, Objekte deiner eigenen Klassen zu vergleichen. Diese Operatoren geben einen bool zurück und sollten als const gekennzeichnet werden, da sie keinen der beiden Operanden verändern.
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;
}
};Eine nützliche Technik besteht darin, andere Vergleichsoperatoren anhand derjenigen zu implementieren, die du bereits definiert hast. Sobald du == und < hast, ergeben sich die übrigen ganz natürlich:
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);
}Dieser Ansatz reduziert die Codeduplizierung und stellt sicher, dass sich alle deine Vergleichsoperatoren konsistent verhalten. Wenn du später änderst, wie Gleichheit oder „kleiner als“ funktioniert, bleiben die anderen Operatoren automatisch synchron.
Aufgabe
EinfachErstellen wir eine Version-Klasse, die Softwareversionsnummern (wie 2.1.0 oder 3.0.5) darstellt und alle sechs Vergleichsoperatoren unterstützt. Dies ist ein praktischer Anwendungsfall, bei dem der Vergleich von Versionen bestimmt, welche Software neuer ist – perfekt, um die Überladung von Vergleichsoperatoren zu üben.
Du erstellst zwei Dateien, um deinen Code zu organisieren:
Version.h: Definiere eineVersion-Klasse, die drei Ganzzahlen speichert, welche die Versionsnummern major, minor und patch darstellen. Deine Klasse sollte Folgendes unterstützen:- Einen Konstruktor, der Werte für major, minor und patch entgegennimmt
- Getter für jede Komponente:
getMajor(),getMinor(),getPatch()(alle const) - Alle sechs Vergleichsoperatoren:
==,!=,<,>,<=,>= - Eine
toString()-Methode, die die Version als String im Format"major.minor.patch"zurückgibt
Implementiere
==und<direkt und definiere anschließend die verbleibenden vier Operatoren mithilfe dieser beiden. Vergleiche bei der Kleiner-als-Prüfung zuerst major, dann minor, falls die Werte für major gleich sind, und anschließend patch, falls sowohl major als auch minor gleich sind. Alle Vergleichsoperatoren sollten const-Memberfunktionen sein.main.cpp: Lies sechs Ganzzahlen aus der Eingabe, die zwei Versionen darstellen (major1, minor1, patch1, major2, minor2, patch2 in separaten Zeilen). Erstelle zweiVersion-Objekte und vergleiche sie mithilfe all deiner Operatoren.Ausgabeformat:
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>Gib für jedes Vergleichsergebnis
trueoderfalse(in Kleinbuchstaben) aus.
Die zentrale Technik besteht hier darin, die vier abgeleiteten Operatoren (!=, >, <=, >=) ausschließlich mithilfe von == und < zu implementieren. Dadurch wird Code-Duplikation reduziert und sichergestellt, dass alle Operatoren konsistent bleiben, falls du die Vergleichslogik irgendwann änderst.
Konvertiere Eingabe-Strings mithilfe von std::stoi() in Ganzzahlen. Verwende std::to_string(), um den Versions-String zu erstellen. Vergiss die Header-Guards in deiner Header-Datei nicht.
Probier es selbst
#include <iostream>
#include <string>
#include "Version.h"
using namespace std;
int main() {
// Lies sechs Ganzzahlen für zwei Versionen
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: Erstelle zwei Version-Objekte
// TODO: Gib Version 1 und Version 2 mit toString() aus
// TODO: Vergleiche mit allen sechs Operatoren und gib die Ergebnisse aus
// Verwende "true" oder "false" (Kleinbuchstaben) für jeden Vergleich
// Format: "v1 == v2: true" oder "v1 == v2: false"
return 0;
}
Diese Lektion enthält ein kurzes Quiz. Starte die Lektion, um es zu beantworten und deinen Fortschritt zu speichern.
Alle Lektionen in Objektorientierte Programmierung
1Grundlagen der OOP
Externe DateienC++ Build & KompilierungHeader-Dateien & QuelldateienNamensräume & GültigkeitsbereicheEinführung in OOP in C++Klassen vs. ObjekteDer 'this'-PointerMethoden (Elementfunktionen)Attribute (Datenelemente)Grundlagen zu Ctors & DtorsRückblick - Einfacher Taschenrechner4Klasseneigenschaften
Instanz- vs. statische MemberGetter und SetterConst-MemberfunktionenMutable-SchlüsselwortStatische Methoden und VariablenFriend-Funktionen & KlassenZusammenfassung - Bankkonto-Manager7Vererbung
Grundlagen der VererbungZugriffsstufen bei VererbungAufrufreihenfolge von Ctor & DtorÜberschreiben von MethodenVirtuelle Funktionen & VTableMehrfachvererbungVirtuelle VererbungRückblick - Mitarbeiter-Hierarchie2Speicherverwaltung
Stack vs. Heap SpeicherZeiger und ReferenzenDynamischer Speicher (new/delete)Smart Pointers in C++RAII in C++Rückblick – Dynamischer Array-Manager5Kapselung
Zugriffsspezifizierer in C++Zugriffsspezifizierer im DetailInformation HidingStruct vs. ClassVerschachtelte & innere KlassenRückblick - Studentenverwaltungssystem8Polymorphie
Kompilierzeit- vs. Laufzeit-PolymorphieFunktionsüberladungVirtuelle Funktionen – WiederholungRein virtuelle FunktionenAbstrakte KlassenInterface-Design in C++Dynamic Casting & RTTIZusammenfassung – Formen-Rechner3Konstruktoren & Destruktoren
StandardkonstruktorParametrisierter KonstruktorKopierkonstruktorVerschiebekonstruktorKonstruktor-InitialisierungslistenDelegierende KonstruktorenDestruktoren im DetailRule of Three / Five / ZeroZusammenfassung - String-Klasse6Operatorüberladung
Einführung in die OperatorüberladungArithmetische OperatorüberladungVergleichsoperatorüberladungStream-OperatorenZuweisungsoperatorüberladungÜberladen der [] und () OperatorenTypumwandlungsoperatorenRückblick - Matrix-Klasse9Templates
FunktionstemplatesKlassentemplatesTemplate-SpezialisierungVariadische TemplatesSFINAE & Type Traits GrundlagenRückblick - Generische ContainerÜbe selbstständig: Online-C++-Compiler