本文へスキップ
BecomeCoder

C++コース · 第12章 演算子オーバーロードとコピー/ムーブ · レッスン49

演算子オーバーロード ― 自作型に演算子を与える

ブラウザで完結

導入

std::string+ で連結できたように、自分で作った型にも +==<< を使えるようにできます。これが「演算子オーバーロード」です。数学的な型(ベクトル・複素数・分数など)で特に便利です。

説明

operator+ のように「operator + 記号」という名前の関数を定義します。Vec2 a, b; に対して a + b と書けるようにしてみましょう。

#include <iostream>
using namespace std;

struct Vec2 {
    double x, y;

    Vec2 operator+(const Vec2& other) const {   // a + b を定義
        return Vec2{ x + other.x, y + other.y };
    }
    bool operator==(const Vec2& other) const {  // a == b を定義
        return x == other.x && y == other.y;
    }
};

int main() {
    Vec2 a{1, 2}, b{3, 4};
    Vec2 c = a + b;              // operator+ が呼ばれる
    cout << c.x << ", " << c.y << endl;   // 4, 6
    cout << (a == a) << endl;    // 1(true)
    return 0;
}

cout << v で自作型を表示できるようにするには、operator<< を定義します。これはクラスの外に、friend を使って書くのが定石です。

flowchart LR
  code["cout &lt;&lt; v"] --> op["operator&lt;&lt;(ostream&amp;, const Vec2&amp;)"]
  op --> out["ostream に x, y を書き込む"]
#include <iostream>
using namespace std;

struct Vec2 {
    double x, y;
    // friend にすると private にもアクセスでき、外部関数として定義できる
    friend ostream& operator<<(ostream& os, const Vec2& v) {
        os << "(" << v.x << ", " << v.y << ")";
        return os;   // つなげて書けるよう ostream を返す
    }
};

int main() {
    Vec2 v{3, 4};
    cout << v << endl;   // (3, 4)
    return 0;
}

まとめ

operator記号 という関数を定義すると、自作型に演算子を与えられます。<<friend の外部関数として書き、ostream& を返して連結できるようにします。ただし乱用は禁物で、「直感的に意味が通る」ときだけ使いましょう。

実際に動かしてみよう

下のエディタにC++を書いて「コンパイル & 実行」を押すと、ブラウザ内で本物のC++コンパイラ(clang + libc++)がその場でコンパイルして実行し、出力が表示されます。std::string・vector・クラス・テンプレート・STL などモダンC++がそのまま動きます。本文の例を書き換えて試しながら進めましょう(初回だけコンパイラの読み込みに時間がかかります。以降はキャッシュされます。この回は標準入力(cin)は使わず、値はコードに直接書きます)。

C/C++ — ブラウザ内で本物のコンパイラで実行

ブラウザ内で本物のC/C++コンパイラ(clang + libc++ / WebAssembly)を動かします。構造体・malloc/free・std::string・vector・クラス・テンプレート・STL などがそのまま実行できます(初回のみコンパイラの読み込みに時間がかかります。以降はブラウザにキャッシュされます)。
スクロールして表示された時点でも自動で読み込まれます。