比較演算子のオーバーロード
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;
}
};便利なテクニックは、すでに定義した比較演算子を使って、他の比較演算子を実装することです。== と < があれば、残りも自然に導き出せます。
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);
}このアプローチにより、コードの重複が減り、all your comparison operators が一貫して動作するようになります。後から等価性や less-than の動作を変更しても、other operators は自動的に同期された状態を保ちます。
チャレンジ
簡単Version class を作成して、ソフトウェアのバージョン番号(2.1.0 や 3.0.5 など)を表し、6 つの比較 operators をすべてサポートしましょう。これは、バージョンを比較してどのソフトウェアが新しいかを判断する実用的なユースケースであり、comparison operator のオーバーロードを練習するのに最適です。
コードを整理するために、2 つのファイルを作成します。
Version.h: major、minor、patch のバージョン番号を表す 3 つの integers を格納するVersionclass を define します。class は次をサポートする必要があります。- major、minor、patch の値を受け取る Constructor
- 各コンポーネントの Getters:
getMajor()、getMinor()、getPatch()(すべて const) - 6 つすべての comparison operators:
==、!=、<、>、<=、>= - バージョンを
"major.minor.patch"の形式の string として返すtoString()method
==と<を直接 Implement し、残りの 4 つの operators はこの 2 つを使って define します。less-than の comparison では、まず major を比較し、major が等しい場合は minor を比較し、major と minor の両方が等しい場合は patch を比較します。すべての comparison operators は const member functions にする必要があります。main.cpp: 2 つのバージョンを表す 6 つの integers(major1、minor1、patch1、major2、minor2、patch2)を、それぞれ別の line から入力します。2 つのVersionobjects を Create し、すべての operators を使って比較します。Output 形式:
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>各 comparison result について、
trueまたはfalse(lowercase)を Print します。
ここでの key technique は、4 つの derived operators(!=、>、<=、>=)を == と < だけを使って Implement することです。これにより code duplication が減り、comparison logic を変更した場合でも、すべての operators の一貫性が保たれます。
入力 strings を std::stoi() を使って integers に変換します。バージョン string の構築には std::to_string() を使用します。header file の header guards を忘れないでください。
自分で試してみよう
#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++オンラインコンパイラ