Self assignment is when someone assigns an object to itself. For example,
Obviously no one ever explicitly does a self assignment like the above, but since more than one pointer or reference can point to the same object (aliasing), it is possible to have self assignment without knowing it:
[ Top | Bottom | Previous section | Next section | Search the FAQ ]
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:
If someone assigns a Fred object to itself, line #1 deletes both
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 evaluatingnew 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.
[ Top | Bottom | Previous section | Next section | Search the FAQ ]
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:
Example 1a:
Example 1b:
Or equivalently:
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.
[ Top | Bottom | Previous section | Next section | Search the FAQ ]
Yes (if you need to define an assignment operator in the first place).
If you define your own assignment operator, the compiler will not automatically call your base class's assignment operator for you. Unless your base class's assignment operator itself is broken, you should call it explicitly from your derived class's assignment operator (again, assuming you create one in the first place).
However if you do not create your own assignment operator, the one that the compiler creates for you will automatically call your base class's assignment operator.
Example:
[ Top | Bottom | Previous section | Next section | Search the FAQ ]
E-mail the author
[ C++ FAQ
| Table of contents
| Subject index
| About the author
| ©
| Download your own copy ]
Revised Jun 26, 2011