비교 연산자 오버로딩
Coddy C++ 여정의 객체 지향 프로그래밍 섹션에 포함된 레슨 — 104개 중 42번째.
==, !=, <code><, , <=, >=와 같은 비교 연산자를 사용하면 사용자 정의 클래스의 객체를 비교할 수 있습니다. 이 연산자들은 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;
}
};유용한 기법 중 하나는 이미 정의한 연산자들을 사용하여 다른 비교 연산자들을 구현하는 것입니다. ==와 <code><가 준비되면, 나머지는 자연스럽게 따라옵니다:
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);
}이 접근 방식은 코드 중복을 줄이고 모든 비교 연산자가 일관되게 작동하도록 보장합니다. 나중에 같음(equality)이나 작음(less-than)이 작동하는 방식을 변경하더라도, 다른 연산자들은 자동으로 동기화된 상태를 유지합니다.
챌린지
쉬움소프트웨어 버전 번호(예: 2.1.0 또는 3.0.5)를 나타내고 6개의 비교 연산자를 모두 지원하는 Version 클래스를 만들어 보겠습니다. 이는 어떤 소프트웨어가 더 최신인지 결정하기 위해 버전을 비교하는 실제 사례로, 비교 연산자 오버로딩을 연습하기에 완벽합니다.
코드를 정리하기 위해 두 개의 파일을 생성합니다:
Version.h: 주(major), 부(minor), 패치(patch) 버전 번호를 나타내는 세 개의 정수를 저장하는Version클래스를 정의합니다. 클래스는 다음을 지원해야 합니다:- major, minor, patch 값을 받는 생성자
- 각 구성 요소에 대한 Getter:
getMajor(),getMinor(),getPatch()(모두 const) - 6개의 모든 비교 연산자:
==,!=,<,>,<=,>= - 버전을
"major.minor.patch"형식의 문자열로 반환하는toString()메서드
==와<를 직접 구현한 다음, 나머지 4개의 연산자를 이 두 연산자를 사용하여 정의하세요. 작음(less-than) 비교의 경우, major를 먼저 비교하고, major가 같으면 minor를 비교하고, major와 minor가 모두 같으면 patch를 비교합니다. 모든 비교 연산자는 const 멤버 함수여야 합니다.main.cpp: 입력에서 두 버전(별도의 줄에 major1, minor1, patch1, major2, minor2, patch2)을 나타내는 6개의 정수를 읽습니다. 두 개의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(소문자)를 출력하세요.
여기서 핵심 기술은 ==와 <만을 사용하여 4개의 파생 연산자(!=, >, <=, >=)를 구현하는 것입니다. 이렇게 하면 코드 중복이 줄어들고, 나중에 비교 로직을 변경하더라도 모든 연산자가 일관성을 유지할 수 있습니다.
std::stoi()를 사용하여 입력 문자열을 정수로 변환하세요. 버전 문자열을 만들 때는 std::to_string()을 사용하세요. 헤더 파일에 헤더 가드(header guards)를 포함하는 것을 잊지 마세요.
치트 시트
비교 연산자(==, !=, <, >, <=, >=)를 사용하면 사용자 정의 클래스의 객체를 비교할 수 있습니다. 이 연산자들은 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);
}직접 해보기
#include <iostream>
#include <string>
#include "Version.h"
using namespace std;
int main() {
// 두 버전을 위한 6개의 정수 읽기
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: toString()을 사용하여 Version 1과 Version 2 출력
// TODO: 6개의 연산자를 모두 사용하여 비교하고 결과 출력
// 각 비교에 대해 "true" 또는 "false" (소문자) 사용
// 형식: "v1 == v2: true" 또는 "v1 == v2: false"
return 0;
}
이 레슨에는 짧은 퀴즈가 포함되어 있습니다. 레슨을 시작해 문제를 풀고 진행 상황을 기록하세요.