演算子オーバーロードとは、標準演算子(例えば、+、-、*、==)のユーザー定義の動作を独自のクラスに対して定義する機能です。これにより、ユーザー定義型(例えば、ベクトルや行列)を扱う際に、表現力豊かで読みやすいコードを書くことができます。
演算子オーバーロード機構は、C++においてオブジェクトを扱う際に直感的な構文をサポートするために登場しました(例えば、複素数の加算やイテレーターの操作など)。これは基本型と同様の方法で行われます。
演算子オーバーロードがなければ、多くの操作は通常の関数(add(a, b))のように見え、コードの読みやすさが損なわれ、表現力が低下します。しかし、過剰または不適切な使用は混乱やエラーを引き起こします。
C++では、演算子の大部分を、関連するメンバー関数または友達関数を宣言することによってオーバーロードできます。新しい操作のロジックを定義します。
コード例:
class Vector2D { double x, y; public: Vector2D(double x, double y) : x(x), y(y) {} Vector2D operator+(const Vector2D& rhs) const { return Vector2D(x + rhs.x, y + rhs.y); } };
主な特徴:
演算子 .(ドット)および ::(コロン)はオーバーロードできますか?
いいえ、演算子 .(ドット)、::、sizeof、?:、およびいくつかの他の演算子はオーバーロードできません—プログラミング言語の標準により。
オーバーロードされた演算子の動作は、標準のセマンティクスと完全に一致する必要がありますか?
必ずしもそうではありませんが、推奨されます(例えば、==をオーバーロードする際は等価性の比較を行うなど)。
オーバーロードされた演算子に対してオブジェクトを値渡しで誤って渡した場合はどうなりますか?
余分なコピーや参照解除が発生し、プログラムが遅くなるかエラーを引き起こす可能性があります。定数参照(const T&)を渡す方が良いです。
コード例:
Vector2D operator+(Vector2D rhs) const; // 非効率的で、オブジェクトがコピーされます。
DataFrameクラスで、スカラー積のために演算子 * をオーバーロードしましたが、副作用(オブジェクトの変更)がありました。
利点:
欠点:
複素数クラスで、+、-、== のオーバーロードが行われ、従来の数学的ロジックが適用され、元のオブジェクトは変更されませんでした。
利点:
欠点: