The following is a base class Bitmap and derived class widget, which defines a private-type pointer PB
class Bitmap {...}; class Widget { ... Private : // ptr to a heap-allocated object};
when overloading the assignment operator "=" in the Widget class, there are a few things to consider:
1 Chain Assignment
The first thing to consider is the case of a chained assignment (chain of assignments), as follows:
int// chain of assignments
The integer 15 is first assigned to Z, the new value of Z is assigned to Y, then the new value of Y is finally assigned to X
());
In order to implement a chain assignment, the return value of the function must be a reference to the instance itself, i.e. *this; Similarly, overloading other compound assignment operators (such as + =,-=, *=,/=), and also having to return *this before the function ends
widget& Widget::operator= (const widget& RHS) { delete pb; // stop using current bitmap New Bitmap (*RHS.PB); // start using a copy of RHS ' s bitmap return *this;}
2 self-assigned value
The second consideration is the case of self-assignment (self-assigment), although the explicit self-assignment is not common, but the potential self-assignment still needs to be noted
Widget W; = W; // explict assignment to self = a[j]; // potential assignmentto self *px = *py; // potential assignment to self
The workaround is to add an if statement inside the function to determine whether the current instance (*this) and the passed parameter RHS are the same instance, that is, the case of self-assignment is judged
If it is self-assigned, it returns *this without any processing, or if it is not self-assigned, first frees the instance itself with memory and then allocates new memory as follows:
widget& Widget::operator= (cosnt widget& rhs) { if (thisreturn *this// identity test:if a self-assignment,does nothing delete PB; New Bitmap (*RHS.PB); return *this;}
3 Exceptional Security
In the above example, if the memory is allocated, because of insufficient memory or Bitmap copy constructor exception, resulting in "new Bitmap" produces an exception (exception), then PB points to a deleted Bitmap
Therefore, in addition to chained assignment and self-assignment, you also need to consider the case of exception security, as shown in the following code: if "New Bitmap" throws an exception, the PB pointer does not change
widget& Widget::operator= (cosnt widget&RHS) {
if (this = = &RHS) return *this; // Identity test
Bitmap*porig = PB;//Remember original PBPB=NewBitmap (*RHS.PB);//Make PB-point-to- a copy DeletePorig;//Delete the original PB return* This;}
If you do not consider the problem of efficiency, then even if there is no judgment on the self-assignment of the IF statement, the following statement is sufficient to deal with the self-assignment problem
4 Copy-Exchange
In the above example, because of the efficiency problem, the IF statement is retained, but in fact, since the probability of self-assignment is very low, the above code appears to be "efficient", but it is not
The most common way to reconcile self-assignment and exception-Safe (Exception safety) is "copy-swap" (Copy-and-swap), as follows:
widget& Widget::operator= (const widget& RHS) { Widget temp (RHS); // Make a copy of RHS ' s data Std::swap (*this// swap *this ' s data with the copy ' s return *this;}
The code above uses the swap function of the standard library, and of course can also customize the swap function
Summary:
1) Overload class assignment operator, first consider the chain assignment --function return *this, second consider self- assignment and exception security --"copy-Exchange"
2) The overloaded class assignment Operator "=" must be defined as a member function, and the other compound assignment operators (such as "+ =", "-=", etc.) should be defined as member functions
Resources:
<effective c++_3rd> Item 10, 11
< Sword finger offer> 2.2.1
Overloaded assignment operator for C + +