C ++ FAQ Lite [12] - Assignment Mode (New)

zhaozj2021-02-08  209

[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

转载请注明原文地址:https://www.9cbs.com/read-2075.html

New Post(0)