在我在 C++ 中学到的所有东西中(不是很多),运算符重载似乎是最困难的。一般而言,何时最好将运算符重载编写为友元函数?我什么时候必须明确使用*this
?使用临时对象总是不好?
4 回答
没有什么神奇的 abort 运算符重载——这样的重载只是名称看起来很奇怪的函数。因此,您编写运算符重载的方式与编写命名函数的方式相同。事实上,首先编写一个命名函数通常是一个好主意——你以后总是可以将它更改为一个运算符。
您唯一需要注意的是编译器使用了几个运算符:
- 将东西存储在集合中时 operator=()
- 排序/搜索时操作符<()
尼尔的回答是正确的。此外,这个链接提供了很多关于何时、何地、为什么以及如何在 C++ 中使用各种类型的运算符重载的有用信息。
一般来说,我会尝试坚持使用直观的重载——“+”运算符的使用应该反映类似于加法等的东西。如果你发现自己在用“+”运算符或类似的东西进行字符串比较,您可能应该改用标准函数。
运算符重载的第一条规则:不要重载没有意义的运算符。例如,+ 运算符可能看起来像是将元素附加到列表的好选择,但事实并非如此:不是每个人都会发现这种用法是合乎逻辑的。
关于数学运算符,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
如果您真的想消除大多数临时变量,请查看表达式模板(请参阅 Blitz++、boost.ublas、newmat,...),或等待 C++0x 右值引用。
All operators overloads as member-function take *this as lvalue,so you need friend in cases you don't want it such overload stream operators as << and >>.In most others cases the use of friends is to break the principle of least privilege. Other way to overload an operator ,which wasn't said, is to use a global function.