虽然我觉得前面的答案已经足够好,但我认为需要澄清一下。
运算符(通常)有两种风格
第一个是非成员函数,第二个是成员函数,其参数是操作的“右操作数”,通常返回当前修改的对象。
例如,假设有一个运算符 § 用于类 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 ;
}
通常,您应该更喜欢非成员函数,如果只是因为您不应该将其声明为朋友。因此,使用 non-member non-friend 函数可以增强对象的封装性。
免责声明:还有其他风格,但我将自己限制为算术运算符,如 +、*、/、- 等,以及“可信”运算符原型。
分析你对运算符的使用
+的情况下:
- 每个操作数都需要保持不变,因为
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 会导致有趣(和错误)的结果。
^_^
最后但并非最不重要的一点
我确实在this page 上写了一个运算符重载原型列表。该页面仍在建设中,但它的主要用途(易于复制/粘贴工作原型)可能非常有用...