算術演算子のオーバーロード
CoddyのC++ジャーニー「オブジェクト指向プログラミング」セクションの一部。レッスン 41/104。
+、-、*、/などの算術演算子は、カスタムクラスが組み込みの数値型のように動作するように、一般的にオーバーロードされます。これらの演算子は通常、オペランドを変更するのではなく、新しいオブジェクトを返します。
算術演算子を備えたFractionクラスを次に示します。
class Fraction {
int numerator, denominator;
public:
Fraction(int n, int d) : numerator(n), denominator(d) {}
Fraction operator+(const Fraction& other) const {
return Fraction(
numerator * other.denominator + other.numerator * denominator,
denominator * other.denominator
);
}
Fraction operator*(const Fraction& other) const {
return Fraction(numerator * other.numerator,
denominator * other.denominator);
}
};どちらのオペレーターも、いずれのオペランドも変更しないため、constとしてマークされていることに注目してください。これらは結果を持つ新しいFractionを作成して返します。
+= のような複合代入演算子では、パターンが異なります。これらは左オペランドを変更し、それへの参照を返します。
Fraction& operator+=(const Fraction& other) {
numerator = numerator * other.denominator + other.numerator * denominator;
denominator = denominator * other.denominator;
return *this;
}一般的な方法は、compound assignment を使って基本演算子を implement し、コードの duplication を減らすことです。
Fraction operator+(const Fraction& other) const {
Fraction result = *this; // このオブジェクトをコピー
result += other; // 複合代入を使用
return result;
}このアプローチにより、両方の演算子の一貫性が保たれ、保守も容易になります。
チャレンジ
簡単算術演算子のオーバーロードを使用して通貨計算を処理する Money クラスを作成しましょう。通常の数値と同じように自然に金額を扱えるよう、複数の算術演算子を Implement します。
コードを整理するために、次の2つのファイルを作成します。
Money.h: 金額をセント単位(intとして)で格納し、floating-point の精度に関する issues を avoid するMoneyclass を define します。class は次をサポートする必要があります。- dollars と cents を別々の整数として受け取る Constructor
- dollar 部分を返す getter
getDollars() - cents 部分(0-99)を返す getter
getCents() - 新しい
Moneyオブジェクトを返すオーバーロードされた+および-演算子 - current オブジェクトを変更し、それへの参照を返す、オーバーロードされた
+=および-=compound assignment 演算子 - 金額を
$X.YYの format(cents は常に2桁)で display するdisplay()method
lesson で示されているように、基本演算子(
+および-)を compound assignment 演算子を使って Implement し、コードの duplication を reduce します。すべての算術演算子には、適切な場合にconstを付ける必要があります。main.cpp: 2つの金額を表す4つの整数(dollars1、cents1、dollars2、cents2 を別々の行に入力)を読み取ります。2つのMoneyオブジェクトを Create し、その後、すべての演算子を実演します。"Amount 1: "を Print し、その後に first の金額を display する"Amount 2: "を Print し、その後に second の金額を display する- 2つの金額を add し、
"Sum: "を Print して、その後に result を表示する - second を first から subtract し、
"Difference: "を Print して、その後に result を表示する +=を使用して second の金額を first に add し、その後"After +=: "を Print して、変更された first の金額を表示する
display() method では、<iomanip> の std::setw(2) と std::setfill('0') を使用して、cents が常に2桁で表示されるようにします(例:$5.07 であり、$5.7 ではありません)。
入力文字列を std::stoi() を使用して整数に変換します。header file の header guards を忘れないでください。
自分で試してみよう
#include <iostream>
#include <string>
#include "Money.h"
using namespace std;
int main() {
// 2つの金額の入力を読み取る
string line;
getline(cin, line);
int dollars1 = stoi(line);
getline(cin, line);
int cents1 = stoi(line);
getline(cin, line);
int dollars2 = stoi(line);
getline(cin, line);
int cents2 = stoi(line);
// TODO: 入力値で2つのMoneyオブジェクトを作成する
// TODO: "Amount 1: "に続いて最初の金額を表示する
// TODO: "Amount 2: "に続いて2番目の金額を表示する
// TODO: 2つの金額を加算し、"Sum: "に続いて結果を表示する
// TODO: 1つ目から2つ目を減算し、"Difference: "に続いて結果を表示する
// TODO: +=を使って2つ目の金額を1つ目に加算し、"After +=: "に続いて変更後の1つ目の金額を表示する
return 0;
}
このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。
オブジェクト指向プログラミングのすべてのレッスン
3コンストラクタとデストラクタ
デフォルトコンストラクタ引数付きコンストラクタコピーコンストラクタムーブコンストラクタコンストラクタ初期化リスト委譲コンストラクタデストラクタ詳解Rule of Three / Five / Zeroまとめ - Stringクラス6演算子オーバーロード
演算子オーバーロード入門算術演算子のオーバーロード比較演算子のオーバーロードストリーム演算子代入演算子のオーバーロード[] と () 演算子のオーバーロード型変換演算子まとめ:Matrix クラス自分で練習してみよう: C++オンラインコンパイラ