以前の回答で十分だと思いますが、明確化が必要だと思います。
オペレーターには (通常) 2 つの種類があります
1 つ目は非メンバ関数で、2 つ目はパラメータが操作の「右側のオペランド」であり、通常は現在変更されているオブジェクトを返すメンバ関数です。
たとえば§
、 classの演算子があるとしT
ます。非メンバー関数のいずれかとして記述できます。
T operator § (const T & lhs, const T & rhs)
{
T result ;
// do the lhs § rhs operation, and puts the result into "result"
return result ;
}
またはメンバー関数として:
T & T::operator § (const T & rhs)
{
// do the "this § rhs" operation, and puts the result into "this"
return *this ;
}
または(非常に珍しい)別のメンバー関数としても:
T T::operator § (const T & rhs) const
{
T result ;
// do the "this § rhs" operation, and puts the result into "result"
return result ;
}
通常、フレンドとして宣言してはならないという理由だけで、非メンバー関数を優先する必要があります。したがって、非メンバー非フレンド関数を使用すると、オブジェクトのカプセル化が強化されます。
免責事項: 他の種類もありますが、ここでは 、 、 、 などの算術演算子と、「信頼できる」演算子のプロトタイプに限定し+
て*
い/
ます-
。
演算子の使用を分析する
の場合+
:
a = b + c
変更してはならないb
ため、各オペランドは定数である必要がありc
ます。
+
のようにを累積できるa = b + c + d + e
ため、一時的なものが存在する必要があります。
T operator § (const T & lhs, const T & rhs)
{
T result ;
// do the lhs § rhs operation, and puts the result into "result"
return result ;
}
の場合+=
:
- 左のオペランド A (A += B から) が変更されることがわかっています。
- 左のオペランド A (A += B から) はそれ自体の結果であることがわかります。
したがって、次を使用する必要があります。
T & T::operator += (const T & rhs)
{
// do the "this § rhs" operation, and puts the result into "this"
return *this ;
}
いつものように、時期尚早の最適化は諸悪の根源です
私はこの種のコードを本番コードで見たので、実際に起こります:
T & operator + (const T & lhs, const T & rhs)
{
static T result ; // result is STATIC !!!!
// do the lhs + rhs operation, and puts the result into "result"
return result ;
}
著者は、一時的に節約したいと考えていました。この種のコードを書くa = b + c + d
と、興味深い (そして間違った) 結果が得られます。
^_^
最後だが大事なことは
私は、このページに演算子のオーバーロード プロトタイプのリストを書きました。このページはまだ作成中ですが、その主な用途 (動作中のプロトタイプを簡単にコピー/貼り付けできる) は非常に便利です...