C++ FAQ Celebrating Twenty-One Years of the C++ FAQ!!!
(Click here for a personal note from Marshall Cline.)
Section 12:
[12.3] OK, OK, already; I'll handle self-assignment. How do I do it?

You should worry about self assignment every time you create a class. This does not mean that you need to add extra code to all your classes: as long as your objects gracefully handle self assignment, it doesn't matter whether you had to add extra code or not.

We will illustrate the two cases using the assignment operator in the previous FAQ:

  1. If self-assignment can be handled without any extra code, don't add any extra code. But do add a comment so others will know that your assignment operator gracefully handles self-assignment:

    Example 1a:

    Fred& Fred::operator= (Fred const& f)
    {
      // This gracefully handles self assignment
      *p_ = *f.p_;
      return *this;
    }
    
    Example 1b:
    Fred& Fred::operator= (Fred const& f)
    {
      // This gracefully handles self assignment
      Wilma* tmp = new Wilma(*f.p_);   // No corruption if this line threw an exception
      delete p_;
      p_ = tmp;
      return *this;
    }
    
  2. If you need to add extra code to your assignment operator, here's a simple and effective technique:
    Fred& Fred::operator= (Fred const& f)
    {
      if (this == &f) return *this;   // Gracefully handle self assignment
      // Put the normal assignment duties here...
      return *this;
    }
    
    Or equivalently:
    Fred& Fred::operator= (Fred const& f)
    {
      if (this != &f) {   // Gracefully handle self assignment
        // Put the normal assignment duties here...
      }
      return *this;
    }
    

By the way: the goal is not to make self-assignment fast. If you don't need to explicitly test for self-assignment, for example, if your code works correctly (even if slowly) in the case of self-assignment, then do not put an if test in your assignment operator just to make the self-assignment case fast. The reason is simple: self-assignment is almost always rare, so it merely needs to be correct - it does not need to be efficient. Adding the unnecessary if statement would make a rare case faster by adding an extra conditional-branch to the normal case, punishing the many to benefit the few.

In this case, however, you should add a comment at the top of your assignment operator indicating that the rest of the code makes self-assignment is benign, and that is why you didn't explicitly test for it. That way future maintainers will know to make sure self-assignment stays benign, or if not, they will need to add the if test.