[12] Assignment Mode (Part of C FAQ Lite, Copyright © 1991-2001, Marshall Cline, Cline@parashift.com)
体,, nicrosoft @ sunistudio.com (East day production room, East day document)
FAQS in section [12]:
[12.1] What is "self-assignment"? [12.2] Why should you be careful to "self-assignment"? [12.3] Good, good; I will deal with self-assignment. But how to do it?
[12.1] What is "self-assignment"?
The self-assignment is to assign the object to itself. E.g,
#include "fred.hpp"
// Declare Fred class
Void Usercode (FRED & X) {x = x;
/ / Self-assignment
}
Obviously, the above code has explicitly self-assigned. But since multiple pointers or references can point to the same object (alias), it is also possible to assign a self-assignment without knowing:
#include "fred.hpp"
//
statement
Fred class
Void Usercode (Fred & X, Fred & Y) {x = Y;
// If & x == & y is possible to be self-assigned
} Int main () {fred z; usercode (z, z);}
[TOP | BOTTOM | Previous Section | Next Section]
[12.2] Why should you be careful to "self-assignment"?
If you don't pay attention to self-assignment, you will make your users suffer very subtle and generally very serious bugs. For example, the following class will lead to disasters in the case of self-assignment:
Class wilma {}; class fred {public: fred (): p_ (new wilma ()) {} fred (const fly & f): p_ (new wilma (* f.p_)) {} ~ fred () {delete p_ ;} Fred & Operator = (const fred & f) {
// Different code: No self-assignment!
Delete p_;
// Line # 1
P_ = new wilma (* f.p_);
// Line # 2
Return * this;} private: wilma * p_;};
If someone assigns the Fred object to itself, because * this and f are the same object, Line # 1 deletes this-> p_ and f.p_. LINE # 2 uses objects that have not existed * f.p_, which is likely to lead to serious disasters.
As the authors of the Fred class, you least be responsible for confident that you have a self-assignment on the Fred object. Don't assume that the user will not do this on the object. If the object crashes due to self-assignment, it is your fault.
In addition: The above-mentioned Fred :: Operator = (const fred &) has a second question: If the new Wilma (* f.p_) is executed, the abnormality (for example, abnormal memory is not enough or Wilma copy constructor) Abnormal
), This-> p_ will become a hanging pointer - the memory it points to is no longer available. This can be solved by creating an object before deleting the object.
[TOP | BOTTOM | Previous section | Next section] [12.3] Good, good; I will deal with self-assignment. But how to do it?
[Recently Reworded The Last Paragraph (on 7/00). Click Here to Go To The Next Faq in The "Chain" of Recent Changes
]
Every moment you create class, you should be careful. This does not mean that you need to add additional code for all your classes: as long as the object is beautifully handled, no matter whether you must add additional code.
If you don't need to add additional code for the assignment, there is a simple and effective technique:
Fred & Fred :: Operator = (const fred & f) {if (this == & f) return * this;
// deal with self-assignment
/ / Write a normal assignment code ...
Return * this;}
Explicit tests are not always necessary. For example, if correcting the previous FAQ
The assignment operator makes it processed New
The abnormality throwing an exception and / or a copy constructor of the Wilma class may write the following code. Note that this code has (happy) automatic access to self-assignment:
Fred & Fred :: Operator = (Const Fred & f) {
// This code is beautifully (but implied) processing self-assignment
Wilma * TMP = New Wilma (* f.p_);
// If the exception is thrown here, there is no problem.
DELETE P_; P_ = TMP; Return * this;}
In the case of this example (self-assignment is harmless but inefficient), some programmers want to improve their self-assignment by adding additional unnecessary tests, such as "if (this == & f) return * this;" Time efficiency. Usually, the self-assignment situation is more efficient, making the non-self-assignment situation more inefficient compromise. For example, adding an IF test of the Fred class as the above IF test makes the non-self-assignment condition (an additional (and unnecessary) conditional branch). If the self-assignment actually occurs once, the IF will waste 99.9% time period.
[TOP | BOTTOM | Previous Section | Next Section]
E-mail the author [C FAQ Lite | Table of Contents | Subject Index | About The Author | © | Download Your Own Copy] Revised Apr 8, 2001