Menu
Coddy logo textTech

Przeciążanie operatorów porównania

Część sekcji Programowanie obiektowe ścieżki C++ w Coddy. Lekcja 42 z 104.

Operatory porównania, takie jak ==, !=, <, >, <= i >=, pozwalają porównywać obiekty własnych klas. Operatory te zwracają wartość bool i powinny być oznaczone jako const, ponieważ nie modyfikują żadnego z operandów.

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;
    }
};

Przydatną techniką jest zaimplementowanie pozostałych operatorów porównania na podstawie tych, które zostały już zdefiniowane. Gdy masz już == i <, reszta wynika z tego naturalnie:

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);
}

To podejście ogranicza powielanie kodu i zapewnia spójne działanie wszystkich operatorów porównania. Jeśli później zmienisz sposób działania operatora równości lub mniejszości, pozostałe operatory automatycznie będą działać spójnie.

challenge icon

Wyzwanie

Łatwy

Zbudujmy klasę Version, która reprezentuje numery wersji oprogramowania (takie jak 2.1.0 lub 3.0.5) i obsługuje wszystkie sześć operatorów porównania. To praktyczny przykład zastosowania, w którym porównywanie wersji pozwala określić, które oprogramowanie jest nowsze — idealny do ćwiczenia przeciążania operatorów porównania.

Utworzysz dwa pliki, aby uporządkować swój kod:

  • Version.h: Zdefiniuj klasę Version, która przechowuje trzy liczby całkowite reprezentujące numery wersji: główny, poboczny i poprawkowy. Twoja klasa powinna obsługiwać:
    • Konstruktor, który przyjmuje wartości głównej, pobocznej i poprawkowej wersji
    • Gettery dla każdego składnika: getMajor(), getMinor(), getPatch() (wszystkie const)
    • Wszystkie sześć operatorów porównania: ==, !=, <, >, <=, >=
    • Metodę toString(), która zwraca wersję jako ciąg znaków w formacie "major.minor.patch"

    Zaimplementuj bezpośrednio operatory == i <, a następnie zdefiniuj pozostałe cztery operatory na podstawie tych dwóch. Przy porównaniu mniejszości najpierw porównaj główny numer wersji, następnie poboczny, jeśli numery główne są równe, a potem poprawkowy, jeśli zarówno główne, jak i poboczne numery są równe. Wszystkie operatory porównania powinny być stałymi funkcjami składowymi.

  • main.cpp: Wczytaj z wejścia sześć liczb całkowitych reprezentujących dwie wersje (major1, minor1, patch1, major2, minor2, patch2, każdą w osobnym wierszu). Utwórz dwa obiekty Version i porównaj je za pomocą wszystkich swoich operatorów.

    Format wyjściowy:

    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>

    Dla każdego wyniku porównania wypisz true lub false (małymi literami).

Kluczową techniką jest tutaj zaimplementowanie czterech operatorów pochodnych (!=, >, <=, >=) przy użyciu wyłącznie == i <. Ogranicza to powielanie kodu i zapewnia spójność wszystkich operatorów, jeśli kiedykolwiek zmienisz logikę porównywania.

Konwertuj ciągi wejściowe na liczby całkowite za pomocą std::stoi(). Do utworzenia ciągu znaków wersji użyj std::to_string(). Nie zapomnij o strażnikach nagłówka w pliku nagłówkowym.

Spróbuj swoich sił

#include <iostream>
#include <string>
#include "Version.h"

using namespace std;

int main() {
    // Wczytaj sześć liczb całkowitych dla dwóch wersji
    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: Utwórz dwa obiekty Version
    
    // TODO: Wyświetl Version 1 i Version 2 za pomocą toString()
    
    // TODO: Porównaj za pomocą wszystkich sześciu operatorów i wyświetl wyniki
    // Użyj "true" lub "false" (małymi literami) dla każdego porównania
    // Format: "v1 == v2: true" lub "v1 == v2: false"
    
    return 0;
}
quiz iconSprawdź się

Ta lekcja zawiera krótki quiz. Zacznij lekcję, żeby na niego odpowiedzieć i śledzić swoje postępy.

Wszystkie lekcje w sekcji Programowanie obiektowe

Poćwicz samodzielnie: Kompilator C++ online