0

So I saw a video talking about operator overloads in a class. This class was a fictitious Number class which instantiated real numbers and could be used like this Number first(1) or Number second(2) (numbers are stored in a num data member) and then we overloaded the operators as member methods , to be able to do this first + second or -first. The code for these operator overloads looked like this:

PS: rhs for right hand side

Number &Number::operator+(const Number &rhs) {
   //perform math calculation between both objects
   return *this;  //return lhs by reference
}

or this for the unary minus operator which just returns the minus version of a single integer (useless but used as an example):

Number operator-() {
   int temp = -num;
   return temp;//temporary
}

Now the video said that we should return an object by reference if it was used in a chain operations after it has gone throught the overload, I also heard it depends of the performance (is it to avoid copying?), but after that I'm still unsure when to return an object by reference or not in class operator overloads.

Thanks in advance.

Alex
  • 840
  • 7
  • 23
  • Do you have the full implementation of `operator+`? – Louis Cloete Apr 03 '20 at 22:42
  • 2
    [Here](https://stackoverflow.com/a/4421719/6639989) you can find a really good explanation about operator overloading general rules. In general, the return type shouldn't depend on whether the operator is overloaded as a member or a non member function. In these specific cases, the `operator+` and `operator-` should return by value, as they should return a new value instead of modifying the object they are called with. – János Benjamin Antal Apr 03 '20 at 22:49
  • Binary non-assigning operations usually should not return a reference, they also usually are const, not modfying their arguments. You binary plus in `a+b` would modify `a` and return it. That's a strategy for `operator+=` – Swift - Friday Pie Apr 05 '20 at 12:36

1 Answers1

1

You can either call the overloaded operator, as either:

  1. Binary Arithmetic Operation: Call an overloaded operator function directly in the same way an ordinary function is called:

    number1 + number2;              // normal expression
    operator+(number1, number2);    // equivalent function call
    

    In this case, both calls are equivalent. Both call the nonmember function operator+, passing number1 as the first argument and number2 as the second. The binary arithmetic operation doesn't modify either operand - it actually returns a new value from the two arguments. Hence you dont return a reference.

  2. Compound Assignment Operation: The other option is to call the member operator function explicitly:

    number1 += number2;             // expression-based call
    number1.operator+=(number2);    // equivalent call to a member operator function 
    

    Here, both the statements, call the member function operator+=, binding this to the address of number1 and passing number2 as an argument. Hence you return it as a reference.

    Number& operator+=(const Number& rhs) // compound assignment
    {                          
        /* addition of rhs to *this takes place here */
        return *this; // return the result by reference
    }
    
mmcblk1
  • 158
  • 1
  • 3
  • 10
  • Thnak you for your answer, however I still don'T understand why I have to return the object by reference in the second example. – Alex Apr 04 '20 at 10:43
  • 1
    Well, the compound assignment operator allows for chaining. So, to perfrom operations such as `(number1 += 1) += 2;`, you need to return the object as reference, because the operation is performed, over and over again on the same object `number1`. If this wasn't returned by reference, then the operation wouldn't be performed on the same object. So, to sum it up, to have consistency with the built-in compound assignment, these operators should return a reference to their left-hand operand. – mmcblk1 Apr 04 '20 at 11:06