【C++】演算子オーバーロードとは?|ゲームのVector2クラスで解説

C++

今回は、C++でよく出てくる「演算子オーバーロードとは何か」について解説していきます。

「演算子オーバーロードって何?」
「自作のVector2を a + b で足したい…」
「なんで自作クラスで +== が使えるようになるの?」

こんな疑問はありませんか?

ゲームでは、座標や速度を表すVector2(2Dベクトル)をよく自作します。そのとき、pos.Add(vel) より pos + vel と書けたほうが直感的ですよね。それを実現するのが演算子オーバーロードです。

この記事を読み終えると、あなたは演算子オーバーロードの意味・書き方・Vector2での活用・初心者がハマりやすいミスをしっかり理解できると思いますので、ぜひ最後まで読んでいただけると嬉しいです。

演算子オーバーロードとは?

演算子オーバーロードとは、自作のクラスに対して +, -, == などの演算子の動きを自分で定義することです。これにより、自作の型でも組み込み型のように演算子で書けるようになります。

まずはクラスの基本を押さえておくとスムーズです(クラスとは?の記事)。

なぜ演算子オーバーロードが必要?

理由は、コードが直感的で読みやすくなるからです。result = a.Add(b.Multiply(2)) より、result = a + b * 2 のほうが数式のまま書けてミスも減ります。特に座標計算が多いゲームでは効果が大きいです。

Vector2で演算子オーバーロード

実際に2Dベクトルの Vector2+ を定義してみましょう。operator+ という名前の関数を書くのがポイントです。

#include <iostream>

struct Vector2 {
    float x = 0.0f;
    float y = 0.0f;

    // + の動きを定義する
    Vector2 operator+(const Vector2& other) const {
        return { x + other.x, y + other.y };
    }
};

int main() {
    Vector2 pos = {10.0f, 5.0f};
    Vector2 vel = {2.0f, -1.0f};

    Vector2 next = pos + vel; // 直感的に足せる!

    std::cout << "次の位置: (" << next.x << ", " << next.y << ")n";
    return 0;
}
次の位置: (12, 4)

pos + vel で座標を更新できました。ベクトルの計算はベクトルの正規化の記事もあわせて読むと理解が深まります。

比較演算子(==)も定義できる

座標が一致しているか調べたいときは == を定義します。

bool operator==(const Vector2& other) const {
    return x == other.x && y == other.y;
}

これで if (a == b) のように、自作の型でも自然に比較できるようになります。

【重要】私が実際に演算子オーバーロードで困った体験談

個人開発でVector2を作ったとき、operator+ の引数を値渡しにしていて、さらに const を付け忘れていました。すると、const な Vector2 同士を足そうとした瞬間にコンパイルエラーが出て「なんで足せないの!?」と混乱しました。

原因は、関数に const が付いていないと const オブジェクトから呼べないこと。引数を const Vector2&、関数の後ろにも const を付けたら、コピーも減って一発で解決しました。「演算子は constconst& をセットで」と覚えてからは詰まらなくなりました。

演算子オーバーロード使用時のよくある失敗例と対処法

①関数にconstを付け忘れる

体験談のとおり、const オブジェクトから使えなくなります。読み取りだけの演算子には後ろに const を付けましょう。

②引数を値渡しにして無駄コピー

引数は const Vector2& で受け取ると、コピーが起きず速くなります。参照の考え方は参照とポインタの記事もどうぞ。

③なんでもオーバーロードして意味不明にする

+ なのに引き算をする、のような直感に反する定義は混乱のもとです。「見た目どおりの意味」になる演算子だけ定義しましょう。

注意点

  • 読み取りだけの演算子は関数の後ろに const を付ける
  • 引数は const 型& で受け取る
  • 演算子の意味は直感どおりに。奇抜な定義は避ける

まとめ

  • 演算子オーバーロードは自作クラスに演算子の動きを定義する仕組み
  • operator+operator== のように書く
  • Vector2の座標計算が数式のまま書けて読みやすい
  • constconst& をセットで付けるのが基本

演算子オーバーロードは、自作の型を組み込み型のように自然に扱える強力な機能です。まずはゲームで使う Vector2+ から定義してみてください。

関連記事