C++ FAQ Celebrating Twenty-One Years of the C++ FAQ!!!
(Click here for a personal note from Marshall Cline.)
Section 12:
[12.2] Why should I worry about "self assignment"?

If you don't worry about self assignment, you'll expose your users to some very subtle bugs that have very subtle and often disastrous symptoms. For example, the following class will cause a complete disaster in the case of self-assignment:

class Wilma { };

class Fred {
  Fred()                : p_(new Wilma())      { }
  Fred(Fred const& f)   : p_(new Wilma(*f.p_)) { }
 ~Fred()                { delete p_; }
  Fred& operator= (Fred const& f)
      // Bad code: Doesn't handle self-assignment!
      delete p_;                // Line #1
      p_ = new Wilma(*f.p_);    // Line #2
      return *this;
  Wilma* p_;
If someone assigns a Fred object to itself, line #1 deletes both this->p_ and f.p_ since *this and f are the same object. But line #2 uses *f.p_, which is no longer a valid object. This will likely cause a major disaster.

The bottom line is that you the author of class Fred are responsible to make sure self-assignment on a Fred object is innocuous. Do not assume that users won't ever do that to your objects. It is your fault if your object crashes when it gets a self-assignment.

Aside: the above Fred::operator= (Fred const&) has a second problem: If an exception is thrown while evaluating new Wilma(*f.p_) (e.g., an out-of-memory exception or an exception in Wilma's copy constructor), this->p_ will be a dangling pointer — it will point to memory that is no longer valid. This can be solved by allocating the new objects before deleting the old objects.