演算子のオーバーロードに関する一般的な規則
次の規則は、オーバーロードした演算子の実装のされ方を抑制します。 ただし、new 演算子と delete 演算子には適用されません。これらについては個別に説明します。
** などの新しい演算子は定義できません。
組み込みのデータ型に適用された場合、演算子の意味は再定義できません。
オーバーロードされた演算子は、非静的クラス メンバー関数またはグローバル関数である必要があります。 プライベートまたはプロテクト クラス メンバーへのアクセスを必要とするグローバル関数は、クラスのフレンドとして宣言する必要があります。 グローバル関数は、クラスまたは列挙型の引数、またはクラスまたは列挙型への参照である引数を 1 個以上受け取る必要があります。 次に例を示します。
// rules_for_operator_overloading.cpp class Point { public: Point operator<( Point & ); // Declare a member operator // overload. // Declare addition operators. friend Point operator+( Point&, int ); friend Point operator+( int, Point& ); }; int main() { }
前のコード サンプルは、メンバー関数として小なり演算子を宣言します。ただし、加算演算子はフレンド アクセスを持つグローバル関数として宣言されます。 複数の実装を特定の演算子に対して提供できることに注意してください。 前の加算演算子の場合は、可換を容易にするため、2 種類の実装が用意されています。 Point を Point に、int を Point に追加する演算子などを実装するようなものです。
演算子は、組み込み型との一般的な使用方法によって指定されるオペランドの優先順位、グループ、および数に従います。 したがって、"2 と 3 を型 Point のオブジェクトに加算" (2 を x 座標に加算し、3 を y 座標に加算する) という概念を表現する手段はありません。
メンバー関数として宣言された単項演算子は引数を受け取りません。グローバル関数として宣言された場合は、引数を 1 つ受け取ります。
メンバー関数として宣言された二項演算子は引数を 1 つ受け取ります。グローバル関数として宣言された場合は、引数を 2 つ受け取ります。
演算子を単項演算子または二項演算子 (&、*、+、および -) として使用できる場合は、使用するたびに個別にオーバーロードできます。
オーバーロードされた演算子は、既定の引数を持つことができません。
代入 (operator=) を除くすべてのオーバーロードされた演算子は派生クラスに継承されます。
メンバー関数のオーバーロードされた演算子の最初の引数は、常に演算子が呼び出されたオブジェクトのクラス型です (演算子が宣言されたクラス、またはそのクラスから派生したクラス)。 最初の引数に対して変換の指定はありません。
どの演算子も意味を完全に変更できることに注意してください。 これは、アドレス演算子 (&)、代入演算子 (=)、および関数呼び出し演算子の意味を含みます。 また、組み込みの型に依存できる ID は、演算子のオーバーロードを使用して変更できます。 たとえば、次の 4 つのステートメントは、通常、完全に評価される場合は等価です。
var = var + 1;
var += 1;
var++;
++var;
演算子をオーバーロードするクラス型では、この ID に依存できません。 また、基本型に対してこれらの演算子の使用が暗黙に必要とされていた条件は一部オーバーロードされる演算子に対して緩和されています。 たとえば、加算代入演算子の += では、基本型に適用される場合は左側のオペランドが左辺値であることが必要です。演算子がオーバーロードされる場合、このような要件はありません。
注意
一貫性のために、オーバーロードされた演算子を定義する場合、組み込み型のモデルに従うことをお勧めします。オーバーロードされた演算子のセマンティクスが他のコンテキストではその意味とは大きく異なる場合、便利というよりも混乱を招く可能性があります。