I l@ve RuBoard | ![]() ![]() |
Solution![]() Short answer: In most cases, it's bad only if, without the test, self-assignment is not handled correctly. Although this check won't protect against all possible abuses, in practice it's fine as long as it's being done for optimization only. In the past, some have suggested that multiple inheritance affects the correctness of this problem. This is not true, and it's a red herring. Exception Safety (Murphy)If T::operator=() is written using the create-a-temporary-and-swap idiom (see page 47), it will be both strongly exception-safe and not have to test for self-assignment. Period. Because we should normally prefer to write copy assignment this way, we shouldn't need to perform the self-assignment test, right? Guideline
Yes and no. It turns out that there are two potential efficiency costs when not checking for self-assignment.
In practice, if self-assignment happens often (rare, in most programs) and the speed improvement gained by suppressing unnecessary work during self-assignment is significant to your application (even rarer, in most programs), check for self-assignment. Guideline
Operator Overloading (Machiavelli?)Because classes may provide their own operator&(), the test in question may do something completely different than is intended. This comes under the heading of "protecting against Machiavelli," though; presumably, the writer of T::operator=() knows whether his class also overloads T::operator&(). Of course, a base class could also provide operator&() in a way that breaks this test. Note that while a class may also provide a T::operator!=(), this is irrelevant because it can't interfere with the "this != &other" test. The reason is that you can't write an operator!=() that takes two T* parameters, because at least one parameter of an overloaded operator must be of class type. Postscript #1:As a bonus, here's a little code joke. Believe it or not, it's been tried by well-meaning (although clearly misguided) coders. T::T( const T& other ) { if( this != &other ) { // ... } } Did you get the point on first reading?[1]
Postscript #2Note that there are other cases in which pointer comparison is not what most people would consider intuitive. Here are a couple of examples.
![]() |
I l@ve RuBoard | ![]() ![]() |