我在C ++中学到的所有东西(并非如此),运算符重载似乎是最困难的。一般而言,何时最好将运算符重载写为友元函数?我什么时候需要明确使用*this
?使用临时对象总是不好的吗?
答案 0 :(得分:4)
没有任何神奇的abourt运算符重载 - 这样的重载只是具有奇怪名称的函数。因此,您编写运算符重载的方式与编写命名函数的方式相同。事实上,首先编写一个命名函数通常是一个好主意 - 您可以随时将其更改为运算符。
您唯一需要注意的是编译器会使用您的几个运算符:
答案 1 :(得分:2)
尼尔的回答是正确的。此外,this link提供了很多有关何时,何地,为何以及如何在C ++中使用各种类型的运算符重载的良好信息。
一般情况下,我会尝试使用直观的重载 - 使用'+'运算符应该反映类似于添加的内容等。如果您发现自己正在使用'+'运算符进行字符串比较等等像这样,你应该使用标准函数。
答案 2 :(得分:1)
运算符重载的第一条规则:不要重载没有意义的运算符。例如,+运算符可能看起来是将元素追加到列表的好选择,但事实并非如此:不是每个人都会发现这种用法是合乎逻辑的。
关于数学运算符,friend
是不需要的。
定义它们的典型方法(尊重对称和隐式转换)如下:
struct T {
T& operator+=(T const& rhs) {
// the actual addition code
return *this;
}
};
T const operator+(T const& lhs, T const& rhs) {
return T(lhs) += rhs;
};
但是,该组织不适合Matrix
或Polynomial
等运营商
*=(T const&)
运算符的operator*=(T const&)
乘法不是那么简单。在那里面
例如,我们会在operator*(T const&, T const&)
之上定义operator*()
,如果没有内部数据的访问者,则可以将二进制friend
设为friend
- 这样使用{ {1}}不是封装违规,而是封装强制执行 - 或用于优化目的。
如果你真的想要消除大部分时间,请查看表达式模板(参见Blitz ++,boost.ublas,newmat,...),或者等待C ++ 0x右值引用。
答案 3 :(得分:0)
所有运算符都重载为成员函数将* this作为左值,因此如果你不希望它像过滤流运算符那样你需要朋友<<和>>。在大多数其他情况下,朋友的使用是打破最小特权的原则。 重载运算符的其他方法(未说明)是使用全局函数。