Menu
Coddy logo textTech

Перегрузка операторов сравнения

Часть раздела Объектно-ориентированное программирование путешествия по C++ на Coddy. Урок 42 из 104.

Операторы сравнения, такие как ==, !=, <, >, <= и >=, позволяют сравнивать объекты ваших пользовательских классов. Эти операторы возвращают bool, и их следует пометить как const, поскольку они не изменяют ни один из операндов.

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

Полезный приём — реализовать остальные операторы сравнения через те, которые вы уже определили. После того как у вас есть == и <, остальные следуют естественным образом:

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

Этот подход уменьшает дублирование кода и гарантирует согласованную работу всех операторов сравнения. Если позже вы измените принцип работы равенства или оператора «меньше», остальные операторы автоматически останутся синхронизированными.

challenge icon

Задание

Легко

Давайте создадим класс Version, представляющий номера версий программного обеспечения (например, 2.1.0 или 3.0.5) и поддерживающий все шесть операторов сравнения. Это практический пример, в котором сравнение версий определяет, какая версия программного обеспечения новее, — идеально для практики перегрузки операторов сравнения.

Вы создадите два файла, чтобы организовать код:

  • Version.h: определите класс Version, который хранит три целых числа, представляющих номера версий major, minor и patch. Ваш класс должен поддерживать:
    • конструктор, принимающий значения major, minor и patch
    • геттеры для каждого компонента: getMajor(), getMinor(), getPatch() (все const)
    • все шесть операторов сравнения: ==, !=, <, >, <=, >=
    • метод toString(), возвращающий версию в виде строки в формате "major.minor.patch"

    Реализуйте == и < напрямую, затем определите остальные четыре оператора через эти два. Для сравнения «меньше чем» сначала сравнивайте major, затем minor, если значения major равны, и затем patch, если и major, и minor равны. Все операторы сравнения должны быть константными функциями-членами.

  • main.cpp: считайте из входных данных шесть целых чисел, представляющих две версии (major1, minor1, patch1, major2, minor2, patch2 в отдельных строках). Создайте два объекта Version и сравните их с помощью всех ваших операторов.

    Формат вывода:

    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>

    Выводите true или false (в нижнем регистре) для каждого результата сравнения.

Ключевой приём здесь — реализация четырёх производных операторов (!=, >, <=, >=) с использованием только == и <. Это уменьшает дублирование кода и гарантирует согласованность всех операторов, если вы когда-либо измените логику сравнения.

Преобразуйте входные строки в целые числа с помощью std::stoi(). Используйте std::to_string() для создания строки версии. Не забудьте о защите от повторного включения в заголовочном файле.

Попробуйте сами

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

using namespace std;

int main() {
    // Прочитать шесть целых чисел для двух версий
    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: Создать два объекта Version
    
    // TODO: Вывести Version 1 и Version 2 с помощью toString()
    
    // TODO: Сравнить с использованием всех шести операторов и вывести результаты
    // Используйте "true" или "false" (строчными буквами) для каждого сравнения
    // Формат: "v1 == v2: true" или "v1 == v2: false"
    
    return 0;
}
quiz iconПроверьте себя

В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.

Все уроки раздела Объектно-ориентированное программирование

Потренируйтесь самостоятельно: Онлайн-компилятор C++