0

In c++, why we must overloading +=, -=, +, - operator beside just overloading + and - operator? Here is an example:

In C++, when I create a Point class, I will do:

class Point {
public:
    int x, y;
public:
    Point(int X, int Y) : x(X), y(Y) {}
    //Assignment operator
    void operator=(Point a) { x = a.x; y = a.y; }
    //The += and -= operator, this seem problematic for me. 
    void operator+=(Point a) { x += a.x; y += a.y; }
    void operator-=(Point a) { x -= a.x; y -= a.y; }
    //The + and - operator
    Point operator+(Point a) { return Point(x + a.x, y + a.y); }
    Point operator-(Point a) { return Point(x - a.x, y - a.y); }
};

But in some other language like C# for example, we don't need to overloading the += and -= operator:

public class Point {
    public int x, y;
    public Point(int X, int Y) {
        x = X; y = Y;
    }
    //We don't need to overloading =, += and -= operator in C#, all I need to do is overload + and - operator
    public static Point operator+(Point a, Point b) { return Point(a.x + b.x, a.y + b.y); }
    public static Point operator-(Point a, Point b) { return Point(a.x - b.x, a.y - b.y); }
}

And both will work same as c++!

So I already know that if we overloading like c++, we can easier control which operator this class can have. But what else it can do?

I'm also new in c++ and I just learn overloading operator today.

Higg 2020
  • 15
  • 5
  • Because `+=` and `-=` can fundamentally be more efficient than `+` and `-` (the latter need to create a new object, after all). So if anything it makes sense to implement `+` and `-` in terms of `+=` and `-=`, not the other way round. – Konrad Rudolph Apr 25 '22 at 09:40
  • @KonradRudolph So you actually mean overloading `+=` and `-=` is faster? – Higg 2020 Apr 25 '22 at 09:44
  • There is no **must** in this situation. You are *allowed* to implement both, but you are also at liberty to only implement one or the other. It's your decision. If you do implement both, you can implement the one in terms of the other. That has the benefit of less code, and the logic is in one place so you don't have to remember to update them in tandem. – Eljay Apr 25 '22 at 11:25

2 Answers2

2

The typical operator+= is more efficient than a = a + b, and cannot be implemented in terms of operator+. It can be the other way around though:

struct foo {
    int value = 42;
    foo& operator+=(const foo& other) {
         this.value += other.value;
         return *this;
    }
    foo operator+(const foo& other) const {
         foo result = *this;
         result += other;   // reuse operator+=
         return result;
    }
};

Note how operator+ must create a new instance, while operator+= merely adds member of already existing instances.

In general operator+= can do something else entirely and might not be related to operator+ at all.

The same holds for operator-= vs operator-.

MSalters
  • 173,980
  • 10
  • 155
  • 350
463035818_is_not_an_ai
  • 109,796
  • 11
  • 89
  • 185
  • It was a little bit confused but I think I can understand it. – Higg 2020 Apr 25 '22 at 09:51
  • 1
    Also note that `operator+=` is non-const. `operator+` can be `const` and still reuse `operator+=` because only the new object `result` is modified. – MSalters Apr 25 '22 at 09:57
1

The questions that should be asked are rather:

  1. Why C# wont allow overloading assignment operator?
  2. Why C++ can't automatically do += if you have overloaded '+' and '=' operators?

The first question is discussed here with an excellent answer: https://stackoverflow.com/a/599582/6035486 TDLR; Due to garbage collection and reference counting, the compiler must be sure that the left side operand of an assignment statement (which is a reference because in C# class instances are references) is invalidated during the assignment hence its reference count must decrease by one. If user-defined assignment logic is allowed and anything can happen in an assignment operator, this mechanism of garbage collection would not work. Sorry this was supposed to be TLDR.

The answer to the second question is the same reason why defining operator== won't automatically give you operator!= and it should also be defined separately.

kdcode
  • 524
  • 2
  • 7