实现运算符重载的最佳方法是什么?

时间:2009-04-22 12:24:51

标签: c++ operator-overloading

我在C ++中学到的所有东西(并非如此),运算符重载似乎是最困难的。一般而言,何时最好将运算符重载写为友元函数?我什么时候需要明确使用*this?使用临时对象总是不好的吗?

4 个答案:

答案 0 :(得分:4)

没有任何神奇的abourt运算符重载 - 这样的重载只是具有奇怪名称的函数。因此,您编写运算符重载的方式与编写命名函数的方式相同。事实上,首先编写一个命名函数通常是一个好主意 - 您可以随时将其更改为运算符。

您唯一需要注意的是编译器会使用您的几个运算符:

  • operator =()在集合中存储事物时
  • 运算符<()在排序/搜索内容时

答案 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;
};

但是,该组织不适合MatrixPolynomial等运营商 *=(T const&)运算符的operator*=(T const&)乘法不是那么简单。在那里面 例如,我们会在operator*(T const&, T const&)之上定义operator*(),如果没有内部数据的访问者,则可以将二进制friend设为friend - 这样使用{ {1}}不是封装违规,而是封装强制执行 - 或用于优化目的。

如果你真的想要消除大部分时间,请查看表达式模板(参见Blitz ++,boost.ublas,newmat,...),或者等待C ++ 0x右值引用。

答案 3 :(得分:0)

所有运算符都重载为成员函数将* this作为左值,因此如果你不希望它像过滤流运算符那样你需要朋友<<和>>。在大多数其他情况下,朋友的使用是打破最小特权的原则。 重载运算符的其他方法(未说明)是使用全局函数。