Reading notes effective C + + Item 11 handling self-assignment in operator=

Source: Internet
Author: User

1. How self-assignment happens

When an object is delegated to itself, self-assignment occurs:

1 class Widget {...}; 2 3 Widget W; 4 5 ... 6 7 // assignment to self,

This may seem foolish, but it is legal, so be assured that the client can do so. In addition, self-assignment is not always easy to discern. As an example:

1 // potential assignment to self

The above code in the case of I and J is equal to the self-assignment, the same, look at the following example:

// potential assignment to self

If the PX and py happen to point to the same thing, then the above statement is the self-assigned value. These are not so obvious that self-assignment is the result of using aliases: that is, you use more than one method to point to the same object . In general, when we manipulate references and pointers to different objects of the same type, we need to consider whether these different objects are the same object. In fact, if two objects come from the same inheritance system, these two objects do not even have to be declared to be of the same type, because pointers or references to base classes can point to derived class objects:

1 class Base {...}; 2 3 class  Public Base {...}; 4 5 void dosomething (const/  RB and *PD might actuallybe67  // The same object

2. Handling bad self-assignment can cause you to fall into the trap.

If you follow the advice of Item13 and ITEM14, you will use objects to manage resources, and you can be confident that the objects that manage the resources will run well when they are copied. In this case, your assignment operator is likely to be self-assigning safe, rather than having to go into a particular consideration of the matter. If you're trying to manage resources yourself (if you write a resource management class yourself), you might fall into a trap: The resource was suddenly freed before the resource was exhausted . For example, suppose you create a class to manage a native pointer to a dynamically allocated bitmap object:

1 class Bitmap {...}; 2 3 class Widget {  4  5... 6 7 Private : 8 9 // ptr to a heap-allocated object Ten  One};

The following is an implementation of operator=, ostensibly justified, but because of the existence of self-assignment, it is actually unsafe. (It's not exceptionally secure, we'll handle it a bit)

1widget&2 3Widgets::operator=(Constwidget& RHS)//unsafe impl. of operator=4 5 {6 7 DeletePb//stop using current bitmap8 9PB =NewBitmap (*RHS.PB);//start using a copy of RHS ' s bitmapTen  One return* This;//See Item A  -}

The problem of self-assignment appears inside operator=, *this (Assignment target) and RHS may be the same object. If this is true, delete will not only destroy the bitmap for the current object, but will also destroy the bitmap for ths. At the end of the function, the Widget object should not have been changed by self-assignment, but you will find that now it has a pointer to the deleted object!

3. How to handle self-assignment one: Identify tests to prevent self-assignment 3.1 implementation code

The traditional way to prevent this error is to perform a qualification test at the beginning of the operator= function to see if it is a self-assignment:

1widget& Widget::operator=(Constwidget&RHS)2 3 {4 5 if( This= = &RHS)return* This;//identity Test:if a self-assignment,6 7 // do nothing8 9 DeletePB;Ten  OnePB =NewBitmap (*RHS.PB); A  - return* This; -  the}

3.2 Defects of this method

This method works, but the previous version of operator= is not only self-assigning insecure, but also unusually insecure (exception-unsafe), and the trouble with exceptions in the current version will persist. In particular, if the "new Bitmap" statement produces an exception (because there is not enough memory to allocate or because the Bitmap copy constructor throws an exception), the widget will have a pointer to the deleted Bitmap object. Such pointers are poisonous because you are not able to release them safely. You won't even be able to read them safely. The only safe thing you can do is spend a lot of debugging effort to figure out where the problem is.

4. How to handle self-assignment two: sort the statements

Happily, the way to make operator= safe is also often to make it self-assigning safe. So, we ignore the problem of self-assignment, and focus on achieving exceptional security. ITEM29 more in-depth exploration of exception security, in this article, we only need to observe: some of the statements are carefully sorted to generate exception security (also can achieve self-assignment security) code , That's enough. For example, we just need to be careful not to release PB until a copy of the PB-directed object is complete:

1widget& Widget::operator=(Constwidget&RHS)2 3 {4 5Bitmap *porig = PB;//Remember original PB6 7PB =NewBitmap (*RHS.PB);//Point PB to a copy of RHS ' s bitmap8 9 DeletePorig;//Delete the original PBTen  One return* This; A  -}

Now, if "new BItmap" throws an exception, PB will still not change. In the absence of the identification test, this code is self-assigned, because we make a copy of the source bitmap, let PB point to the copied data, and then delete the source bitmap. This may not be the most efficient way to deal with self-assignment, but this is really a viable approach.

If your relationship is efficient, you can put the code for the discriminant test back to the beginning of the function. But before you do that, ask yourself how often the self-assignment occurs because the identification test is not free. It will add some code (the obj file will also grow) and introduce a branch of process control, both of which will make the program run slower. The efficiency of the prefetching,caching and pipelining directives will be reduced.

5. Method of handling self-assignment three: Copy and Swap5.1 Implementation Method One

Let's take a different approach to manually sort the statements in operator= to ensure self-assignment and exception security at the same time, which is called Copy and swap (copy and swap). This technique is closely related to the safety of the exception, so it is described in Item29. However, it is also a very common way to implement operator=, so it is worthwhile to see what this implementation looks like:

1 classWidget {2 3 ...4 5 voidSwap (widget& RHS);//Exchange *this ' s and RHS ' s data;6 7...//See Item, for details8 9 };Ten  Onewidget& Widget::operator=(Constwidget&RHS) A  - { -  theWidget temp (RHS);//Make a copy of RHS ' s data -  -Swap (temp);//swap *this ' s data with the copy ' s -  + return* This; -  +}

5.2 Implementation Method Two

Using the following two facts we can change the above implementation in a different way: (1) the copy assignment operator of a class can be declared to be passed by value . (2) passing by value copies the values . Here's another way to do this:

1widget& Widget::operator= (Widget RHS)//RHS is a copy of the object2 3{//passed In-note pass by Val4 5Swap (RHS);//swap *this ' s data with6 7 //The copy ' s8 9 return* This;Ten  One}

From a personal point of view, I am concerned that this approach sacrifices the clarity of the code for smart implementations, but it is true that the compiler can sometimes produce more efficient code by moving the copy operation from the function body to the parameters of the function.

Reading notes effective C + + Item 11 handling self-assignment in operator=

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.