Menu
Coddy logo textTech

算術演算子のオーバーロード

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

このアプローチにより、両方の演算子の一貫性が保たれ、保守も容易になります。

challenge icon

チャレンジ

簡単

算術演算子のオーバーロードを使用して通貨計算を処理する Money クラスを作成しましょう。通常の数値と同じように自然に金額を扱えるよう、複数の算術演算子を Implement します。

コードを整理するために、次の2つのファイルを作成します。

  • Money.h: 金額をセント単位(int として)で格納し、floating-point の精度に関する issues を avoid する Money class を 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;
}
quiz icon腕試し

このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。

オブジェクト指向プログラミングのすべてのレッスン

自分で練習してみよう: C++オンラインコンパイラ