重载+ =或 - =运算符的好处

avu*_*nda 5 c++ oop templates operator-overloading complex-numbers

最近,我完成了一项任务,即使用模板重载复杂类的基本功能主义者(+, - ,共轭...).我不得不出汗一点,找出适当的返回类型,(铸造到更高的类型),但最后,我得到它完美的工作.这就是我班级的样子 -

template <typename T> class complex_t
{ 
private:
    T real;
    T imaginary;

public:

complex_t(T X, T Y)
  {
    real=X;
    imaginary=Y;
  }
}
Run Code Online (Sandbox Code Playgroud)

但我没有得到满分,因为我没有实现+ =, - =等运算符.为什么实施这些运营商很重要?这样做是否真的能提供任何特别的好处?谁能分享一些想法?

提前致谢,

Mar*_*tin 9

重载运算符 - 允许类"Foo"的用户编写如下代码:

Foo f1 = ...;
Foo f2 = ...;
f2 = f2 - f1;
Run Code Online (Sandbox Code Playgroud)

重载operator - =允许用户编写

Foo f1 = ...;
Foo f2 = ...;

f2 -= f1;
Run Code Online (Sandbox Code Playgroud)

除非你重载 - =,否则第二个例子将无效,你的用户可能希望这样做.

编辑以纳入效率点 (我的答案正在上升,所以我认为我总结了其他答案中反复出现的一点,将所有细节保持在一个位置.感谢larsmans和Benjamin)

f2 -= f1通常比f2 = f2 - f1两个原因更有效:

  • operator -需要采取的副本this,修改副本,并返回之前.
  • operator - 还需要按值返回结果(它不能返回对堆栈对象的引用),可能导致第二个副本.

operator -=另一方面,修改this到位,所以不复制.


Ben*_*ley 9

如果你有两个对象,A和B,并且你想要通过B增加A,没有operator+=,你会这样做:

A = A + B;
Run Code Online (Sandbox Code Playgroud)

在正常的实现中,这将涉及创建第三个(临时)对象,然后将其复制回A.但是,使用operator+=A可以在适当的位置进行修改,因此通常工作量较少,因此效率更高.

也许更重要的是,这是语言的惯用语.C++程序员期望他们能做到这一点:

A = A + B;
Run Code Online (Sandbox Code Playgroud)

他们也可以这样做:

A += B;
Run Code Online (Sandbox Code Playgroud)

  • 另外,实现`operator + =`作为成员函数可以很容易地将`operator +`编写为自由函数而不会成为朋友:`MyType operator +(const MyType&lhs,const MyType&rhs){return MyType(lhs)+ = rhs ; }`. (3认同)

Fre*_*Foo 6

+=和朋友一起就地工作,所以你不必返回你班级的新实例.对于复杂的数字,这可能不是什么大问题,但是对于更大的结构,复制可能是昂贵的.

例如,假设您在数学意义上实现向量,支持任意长度.

class Vector
{
    std::vector<double> elements;

  public:
    Vector operator+(double x)
    {
        // must return a copy!
        Vector v(*this);
        for (size_t i=0; i < elements.size(); i++)
            v.elements[i] += x;
        return v;
    }

    Vector &operator+=(double x)
    {
        // in-place operation
        for (size_t i=0; i < elements.size(); i++)
            elements[i] += x;
        return *this;
    }
};
Run Code Online (Sandbox Code Playgroud)

  • @Martin:移动语义将部分缓解问题(不是移动构造函数,而是移动赋值运算符).它仍然不必要地创建了第三个对象,但将其复制回f2则效率更高. (2认同)

Zan*_*ane 5

首先,如果你给我一个带+运算符的类,我希望+ =也可以.但是,这不是自动生成的,因此您需要实现它.

其次,正如其他人之前所指出的,取决于你的类的实现和总和操作的定义,你可能能够实现+ =更高效,而不仅仅是以明显的方式重新使用你的+运算符(这是它可以由编译器自动生成的方式,但不是).