I tried to consult the book and the reason I found there is that the prototype of the operator function to overload << operator is:
friend ostream& operator<<(ostream&, const className&);
Now consider the following statement:
cout << myRectangle << yourRectangle;
This statement is equivalent to the statement:
operator<<(operator<<(cout, myRectangle), yourRectangle); //Line A
because the associativity of the operator << is from left to right. To execute the previous statement, you must first execute the expression:
cout << myRectangle
that is, the expression:
operator<<(cout, myRectangle)
After executing this expression, which outputs the value of myRectangle, whatever is returned by the function operator << will become the left-side parameter of the operator << (that is, the first parameter of the function operator<<) in order to output the value of object yourRectangle (see the statement in Line A). The left-side parameter of the operator << must be an object of the ostream type, so the expression: cout << myRectangle must return the object cout (not its value) to the left side of the second operator << in order to output the value of yourRectangle. Therefore, the return type of the function operator<< must be a reference to an object of the ostream type.
That means you cannot pass an object by value as an argument where the formal parameter takes it by reference. So it makes sense to me why do we return by reference when overloading << operator. But where I get confused is in this statement:
tempRectangle = myRectangle + yourRectangle + anyRectangle;
According to the precedence and associativity of the operators, the compiler will first execute:
myRectangle + yourRectangle
Which is equivalent to:
myRectangle.operator+ (yourRectangle); // Line B
► Here comes my first confusion that after executing line B, it will return the object by value (which is then to be added by the third object, i.e. anyRectangle). So how do you write this addition in terms of line B (because we do not have any name to that object which is returned by value, so how does it perform this addition).
► Second confusion is that after adding all the three objects in this statement:
tempRectangle = myRectangle + yourRectangle + anyRectangle;
we have a returned-by-value object, which is then to be passed to operator= function to assign it tempRectangle. Now this is the same case as it happened it << operator. As the prototype of operator= function is :
className operator+(const className&) const;
This function also has a reference parameter. But we passing object by value as an actual parameter (in overloading << operator, we were having return by reference because we had to pass it to reference parameter which could not return by value object so why are we not doing the same here, i.e return by reference).