Operators are of two types: operators with side effects that modify one of their operands (increment / decrement, simple assignment, compound assignments like +=
, etc.), and operators without side effects that do not modify their operands, but return result in a new facility.
It is here that usually passes the "watershed" on the type of the return value.
The former traditionally return a reference to their operand, and the latter, an independent temporary object . (What kind of "bit copy" you are talking about is not clear. The result of the operator usually contains a new value, so it is not clear how it can be a "copy" of something.)
In your example, the assignment operator is implemented just right, but the binary addition operator is implemented terribly crooked.
Your binary addition operator modifies its left operand. Where have you seen it? This is a strange and unexpected behavior for a binary addition operator.
The proper implementation might look like this.
SomeClass operator +(const SomeClass &rhs) const { int new_value = value + rhs.value; return new_value; // <- Используется неявная конверсия `int` к `SomeClass` }
Both operands retain their original values, and the return of the result, of course, is done by value.
But if you wanted to overload the compound assignment operator +=
, then it would look like this
SomeClass &operator +=(const SomeClass &rhs) { value += rhs.value; return *this; }
those. exactly as you wrote, but with the return on the link.
Separately, it should be added that, firstly, such "symmetric" operators with respect to their arguments, such as binary +
, -
, *
, etc. It is recommended to overload with a separate function, not a member function (for example, a friend function). Secondly, if you overload both binary operators and the corresponding compound assignments, then the common idiom is to implement the first through the second
class SomeClass { SomeClass& operator +=(const SomeClass &rhs) { value += rhs.value; return *this; } friend SomeClass operator +(SomeClass lhs, const SomeClass &rhs) { // Обратите внимание, что `lhs` передается по значению lhs += rhs; return lhs; } ... };
"Symmetric" operators are best defined by a separate function, rather than a member function, in order for such operators to behave "symmetrically" with respect to implicit coercions of argument types.
For example, if you set the binary operator +
as shown in my first example, i.e. member function, the following unpleasant asymmetry will be observed
SomeClass a(1), b(2); a = b + 1; // <- OK a = 1 + b; // <- Ошибка: нет такого оператора `+`
those. such an operator will not be considered as a candidate in 1 + b
expressions. Member functions are considered only from the left operand. And in the case of 1 + b
left operand is 1
, which has no member functions at all.
But as soon as you make your binary +
independent function, it will be applied in a symmetric way in both variants.