比較演算子のオーバーロード
CoddyのC++ジャーニー「オブジェクト指向プログラミング」セクションの一部。レッスン 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;
}
};便利なテクニックは、すでに定義した演算子を使って other comparison operators を実装することです。== と < があれば、残りは自然に導けます。
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);
}このアプローチにより、コードの重複が減り、すべての比較演算子が一貫して動作するようになります。後から等価性や小なりの動作を変更しても、他の演算子は自動的に同期された状態を保ちます。
チャレンジ
簡単Version クラスを作成して、ソフトウェアのバージョン番号(2.1.0 や 3.0.5 など)を表し、6 種類すべての比較演算子をサポートしましょう。これは、バージョンを比較してどのソフトウェアが新しいかを判定する実用的なユースケースであり、比較演算子のオーバーロードを練習するのに最適です。
コードを整理するために、次の 2 つのファイルを作成します。
Version.h: major、minor、patch のバージョン番号を表す 3 つの整数を保持するVersionクラスを定義します。クラスには次の機能を持たせます。- major、minor、patch の値を受け取るコンストラクター
- 各コンポーネントのゲッター:
getMajor()、getMinor()、getPatch()(すべて const) - 6 種類すべての比較演算子:
==、!=、<、>、<=、>= - バージョンを
"major.minor.patch"形式の文字列として返すtoString()メソッド
==と<を直接実装し、残りの 4 つの演算子はこの 2 つを使って定義します。小なり比較では、まず major を比較し、major が等しい場合は minor を比較し、major と minor の両方が等しい場合は patch を比較します。すべての比較演算子は const メンバー関数にしてください。main.cpp: 2 つのバージョンを表す 6 個の整数(major1、minor1、patch1、major2、minor2、patch2。各値は別々の行)を入力から読み取ります。2 つの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() を使います。ヘッダーファイルにインクルードガードを記述することも忘れないでください。
自分で試してみよう
#include <iostream>
#include <string>
#include "Version.h"
using namespace std;
int main() {
// 2つのバージョン用に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: 2つの Version オブジェクトを作成する
// TODO: toString() を使用して Version 1 と Version 2 を出力する
// TODO: 6つの演算子すべてを使用して比較し、結果を出力する
// 各比較には "true" または "false"(小文字)を使用する
// 形式: "v1 == v2: true" または "v1 == v2: false"
return 0;
}
このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。
オブジェクト指向プログラミングのすべてのレッスン
3コンストラクタとデストラクタ
デフォルトコンストラクタ引数付きコンストラクタコピーコンストラクタムーブコンストラクタコンストラクタ初期化リスト委譲コンストラクタデストラクタ詳解Rule of Three / Five / Zeroまとめ - Stringクラス6演算子オーバーロード
演算子オーバーロード入門算術演算子のオーバーロード比較演算子のオーバーロードストリーム演算子代入演算子のオーバーロード[] と () 演算子のオーバーロード型変換演算子まとめ:Matrix クラス自分で練習してみよう: C++オンラインコンパイラ