1

Is a self assignment check, example below, required when overloading operator+= and operator-=?

Example:

class A
{
     A operator+=(const A& a)
     {
         if(this != &a)
         {
             // operations
         }

         return *this;
     }
}
FreelanceConsultant
  • 13,167
  • 27
  • 115
  • 225

5 Answers5

5

Is a self assignment check, as exampled below, required when overloading the operaators += and -= in C++?

No, it is not. In fact, it seems wrong to do so.

It is perfectly legal and semantically valid to use:

int i = 10;
i += i;

The expectation here is that i will be set to 20 at the end of that operation.

R Sahu
  • 204,454
  • 14
  • 159
  • 270
3

Is a self assignment check, as exampled below, required when overloading the operaators += and -= in C++?

No it's not required, it's even wrong. The self check applies the wrong semantics here. Why shouldn't it be possible to add A to itself?

Think about an example with a custom string class:

MyString s = "abc";
s += s;

What would an innocent reader expect as the value of s? "abc" or "abcabc"?


Also the operator should return a reference to the current instance:

    A& operator+=(const A& a) {
  // ^ ...
    }
πάντα ῥεῖ
  • 1
  • 13
  • 116
  • 190
2

Since you're mucking with the internal state of the object, it might be necessary to do a "self check" in order to make sure to access the object consistently, but it isn't a self assignment check. a += a certainly shouldn't result in a being unchanged.

sfjac
  • 7,119
  • 5
  • 45
  • 69
1

The self assignment test, e.g. if (this != &a) is normally done for assignment operator operator=(const A& s) for efficiency reasons or to avoid using destroyed data if the operator destroys some members before doing actual assignment. However, even there it is normally indicator of a design problem.

As for operator+= and operator-= it is not required, and what is more, it would be a problem to use it! For e.g. integers, if x == 2

x += x;

should change x to 4. In your classes you should keep the same behaviour: a += a; definitely should modify a.

Wojtek Surowka
  • 20,535
  • 4
  • 44
  • 51
  • Damn... I thought there was a serious need for `if(this != &a)` in `operator=`... Why do people bother with it? Okay for efficiency... but when exactly are you likely to encounter assignment of an instance of `class A` to itself? Seems like a silly reason to add this check... – FreelanceConsultant Mar 12 '16 at 18:06
  • Note: Usually required if object manages a resource. You don't want to `delete[]` the data and then try to copy it! – FreelanceConsultant Mar 12 '16 at 18:10
  • @user3728501 Normally you would not write `x = x`, but when you write `x = some_function_returning_existing_object_from_some_container()` then it may happen. And it is not only done for efficiency - some weakly designed classes can e.g. destroy its data before assignment, so for self assignment it would mean using deleted data. – Wojtek Surowka Mar 12 '16 at 18:10
  • @user3728501 I modified the answer to include situation with `delete[]`. – Wojtek Surowka Mar 12 '16 at 18:16
0

It depends entirely on what it means to "add" your objects. Since your question seems to be of a general nature (where addition may be any operation that can be combined with assignment), I can, off the top of my head, only think of an example with multiplication.

With bignums the multiplication process cannot be done in-place. The destination object must be distinct from the source(s). If not, the multiplication will fail.

I admit that the example isn't perfect. Often, you can avoid asking the question about self-assignment by forcing the issue. A bignum multiply-assign might look like this:

bignum& operator += ( bignum& lhs, const bignum& rhs )
{
  return lhs.swap( lhs + rhs );  // lhs = lhs + rhs
}

This leverages the existing operator+ to perform the multiplication to create a temporary result, which is then assigned intelligently using the bignum's swap() member function (it has one, right?).

Again, this was just an example off the top of my head... and not a perfect one. There might arise situations (and you know how your data is manipulated best) that require a different strategy.

[edit] The good example of avoiding calling delete[] on a resource was made above. [/edit]

tl;dr

If you need to check for self assignment, do it. If you don't, then don't.

Dúthomhas
  • 8,200
  • 2
  • 17
  • 39