虽然我觉得以前的答案已经足够好,但我认为需要进行一些澄清。
运算符(通常)有两种风格
第一个是非成员函数,第二个是成员函数,其参数是操作的“右操作数”,通常返回当前修改的对象。
例如,假设有§
一个类的运算符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
。
+
您可以像 in 一样累积,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
会导致有趣(和错误)的结果。
^_^
最后但并非最不重要的
我确实在这个页面上写了一个运算符重载原型的列表。该页面仍在建设中,但它的主要用途(易于复制/粘贴工作原型)可能非常有用......