目次
- C++ 演算子オーバーロード とは
- グローバル関数による演算子オーバーロード
- メンバ関数による演算子オーバーロード
- その他
- まとめ・参考
C++ 演算子オーバーロード とは
「演算子オーバーロード」とは、+, -, *, / などの演算子を再実装することで、式を楽に、しかも分かりやすく記述するための仕組みだ。
例えば、自作したクラス T のオブジェクト a, b, c があり、「a + b * c」を計算したい場合は、加算を行う
「T add(const T&, const T&)」、乗算を行う「T mul(const T&, const T&)」を定義してやれば、「add(a, mul(b, c))」と記述できる。
これでも一応目的は達せられるのだが、「a + b * c」と記述するのに比べ、手間がかかるし、見てわかりづらいと誰もが思うことだろう。
こういう時こそ演算子オーバーロードの出番だ。
演算子オーバーロードを使うと、型T動詞の + 演算子、*演算子を定義することができ、
計算式を「a + b * c」のように楽にわかりやすく記述することが出来るようになるというわけだ。
その具体的な定義方法は本稿で順次解説していく。
「演算子オーバーロード」と聞くと恐れて近寄らないようにしている人が一部にいるようだが、基本を抑えれば特に難しいことはなく、
覚えて使いこなすととっても楽ができることなので、食わず嫌いにならず、ぜひマスターして欲しい。
ちなみに、演算子オーバーロードの英語表記は「operator oveloading」。 そのままカタカナ表記すると「オーバーローディング」なのだが、日本語では「オーバーロード」と表記することが多いようだ。
なお、本稿はクラスを定義する基本知識を前提としている。それがあやふやな人は C++ クラス 入門 を参照してほしい。
グローバル関数による演算子オーバーロード
演算子オーバーロードを行うには、
- グローバル関数で演算子を再実装する
- クラスメンバ関数として演算子を再実装する
の2種類の方法がある。
この章では、前者の方法について説明する。
「+」「-」「*」「/」などの型Tどうしの 2項演算子は、「T +(const T&, const T&)」のように、 型Tのconst な参照型の引数を2つとって、型Tの値を返す関数とみなす。
T +(const T& a, const T& b) // + 演算子の実装(注意:これは正しくない例) { return a と b を加算した値; }
ただし、「+」は関数名としては文法的に許されないので、演算子の前に「operator」を付加し「operator+(const T&, const T&)」と表記する。
他の演算子でも同様だ。乗算「*」であれば、「operator*(const T&, const T&)」、減算「-」であれば「operator-(const T&, const T&)」となる。
T operator+(const T& a, const T& b) // + 演算子の実装(注意:これは正しくない例) { return a と b を加算した値; }
- 「+」「-」「*」「/」などの2項演算子は、「+(const T&, const T&)」のように、引数を2つとる関数とみなす。
ただし、このままだと構文的に許されないので、演算子の前に「operator」を付加し「operator+(const T&, const T&)」と表記する。
単項演算子は「operator-(const T&)」。
3項演算子は「operator?:(const T&, const T&, const T&)」かと思いきや、実は ?: はオーバロードすることが出来ないぞ。 - 型 operator演算子(仮引数) { ... return 値; }
- 返す型は bool またはクラスオブジェクトへの参照
- 通常、仮引数部分は、const クラス名 &
メンバ関数による演算子オーバーロード
- 型 クラス名::operator演算子(仮引数) { ... return 値; }
その他
- 前置インクリメント・後置インクリメント
- 前置デクリメント・後置デクリメント
インクリメントは前置も後置も「++」なので区別がつかない。そこで後置の方は仮引数型として int を取ることになっている。
前置インクリメントは「operator++()」、後置インクリメントは「operator++(int)」
前置デクリメントは「operator++()」、後置デクリメントは「operator++(int)」