C++ Programming Tips: Return of ‘operator=’ and Self-Assignment Handling

1. ‘operator=’ Must Return a Reference to ‘*this’

The assignment operator has a commonly used form, chained assignment:

C++ Programming Tips: Return of 'operator=' and Self-Assignment Handling

Chained assignment uses right associativity, as mentioned in the comments. The issue arises that for chained assignment to work, the return value inside the parentheses must be of type ‘int’. Similarly, for our user-defined functions to use chained assignment, ‘operator=’ must return the same type.

For performance reasons, we adopt the method of returning a reference to the same type object, thus stipulating that ‘operator=’ must return a reference to ‘*this’:

C++ Programming Tips: Return of 'operator=' and Self-Assignment Handling

2. Self-Assignment in ‘operator=’

Self-assignment refers to the situation where an object is assigned to itself. This error seems obvious and should be caught, but in reality, due to pointers and references, we sometimes do not realize whether they point to the same object, leading to misuse of self-assignment. Consider the following example:

C++ Programming Tips: Return of 'operator=' and Self-Assignment Handling

If it is self-assignment, then the statement ‘delete this->pName;’ not only destroys the current object’s ‘pName’ but also destroys ‘people’s’ ‘pName’. The subsequent statements will use a pointer that points to an already destroyed ‘pName’, which is a very serious error.

3. Self-Assignment Solution: Identity Test (Not Recommended)

This solution is straightforward; before executing ‘operator=’, check if it is self-assignment:

C++ Programming Tips: Return of 'operator=' and Self-Assignment Handling

This intuitively solves the self-assignment problem, but it is not perfect. Upon further thought, if the ‘new’ statement fails to create, an exception will be thrown, but the content originally pointed to by the object’s ‘pName’ has already been destroyed, leading to ‘pName’ pointing to an already destroyed object, which is very dangerous.

4. A Better Solution: Adjusting Statement Order

Consider this code:

C++ Programming Tips: Return of 'operator=' and Self-Assignment Handling

First, create a pointer copy ‘pNameold’ that points to the content of this object’s ‘pName’. After the assignment is complete, use ‘pNameold’ to destroy the old content. This way, whether ‘new’ throws an exception or self-assignment occurs, there are no issues. Of course, this code will have some trade-offs in efficiency.

5. Another Alternative: ‘Copy and Swap’ Technique

Look at the code:

C++ Programming Tips: Return of 'operator=' and Self-Assignment Handling

This method cleverly utilizes value passing, where value passing creates a copy using the copy constructor (which does the ‘new’ work for us), and at the end of the function, the copy is automatically destructed (which does the ‘delete’ work). This method is more efficient in code but sacrifices code readability.

Leave a Comment