Overloaded assignment operators

Source: Internet
Author: User
  Overloaded assignment operator assignment operators may be the most confusing one, so overloading it must be very careful. 1. The   value operator can only be overloaded as a member function. C + + does not allow assignment operators to be overloaded as global, because if the global form of assignment operator functions can be written, we can write such a function:  iint operator= (int A, integer b); Thus appeared such a lawless statement: Integer A (3); 2 = A;//god Save Me 2. Note the value of the self assignment now we write a simple integer class and overload the assignment operator.  class integer {int i; Public:integer (int J): I (j) {};     integer& operator= (const integer& A {    i = A.I     return *this;   };  }; Well, yes. But, wait a minute, you're not considering your own assignment. Ah, is it necessary. Indeed, there is no reason to detect the assignment in this example, but consider the following example: Class CA {public:char* p;    ca () {p = NULL;}; void Set (char* pstr) {&NBSP;&N bsp;  delete []p; if (pstr = = null) {         p = null;} else {p = new Char[strlen (PSTR) +1]; &nbsp ;       strcpy (P, pstr); }  };     ca& operator= (ca& a) {cout<< "operator = invoked/n" <<endl;    // No self assignment detected     delete []p;     p = A.P;    A.P = NULL;    return *this; };     ~ca () {delete []p;}; The};  CA Object "owns" the memory that its member P points to. Therefore, in an assignment function, parameter a discards its "ownership" and forwards it to the calling object. (the smart pointer auto_ptr defined in the C + + logo library is a "owning" smart pointer, and it also has the nature of this "ownership transfer") see the following example code (example code 1): CA A1, A2; A1. Set ("OK"); a2 = A1; Our function seems to work very well, but look at the following statement: A2 = a2;//tragedy occurred, A2 "owned" Memory was released. Therefore, the assignment operator function should be written in the following form: ca& ca::operator= (ca& a) {   cout<< "operator = invoked/n" <<endl;//Check Measure self Assignment if (this!= &a) {delete []p;         p = a.p;     A.P = NULL; return *this; }; Because it is possible to inflict damage on an object while it is being assigned, you must pay attention to the value of the assignment when overloading the assignment operator. The so-called habits become natural, if we develop good habits, we will avoid making mistakes.   So the assignment operator function in the integer class should be written like this: integer& integer::operator= (const integer& a) {        if (this!= &a)     i = A.I; return *this; };   3. Why the assignment operator is not invoked.   Now that our CA class has a "perfect" assignment operator function, let's sit down and write down such a piece of code (example code 2) and wait for it to print out operator = invoked:ca a1; A1. SeT ("OK"); CA&NBSP;A2 = A1; But...... God, our program crashed. Debugging proves that this code does not call the assignment operator function at all, why? If you examine the example code 1 and 2 carefully, you will find that the difference between them is only that the value that is initialized to A1 when A2 is defined in code 2 ... Wait, did you think of something, yes, that's it: Copy the constructor. C + + guarantees that the object will be initialized, so ca a2 = A1; The assignment operator is not invoked but the copy constructor is invoked. Because the copy constructor is not defined in the class, the compiler generates a default copy constructor. And this function is simply bitcopy,a1 "owning" memory is not transferred to A2, so that the memory is "owned" by two objects, when the object destructor, it was delete two times, so tragedy happened. So, we need to define our own copy constructors: class CA {public:     CA (ca& a)    {    &NBSP;&NBSP;&NB Sp cout<< "copy Constructor" <<endl;         p = A.P;         A.P = NULL;    } ...}; Because parameters are changed in the function, the parameters cannot be defined as const. There is no problem with executing code 1 or code 2 now. Before this part is over, let me ask you a question: what happens if we change the return value type of the assignment operator function from ca& to CA? OK, let's execute example code 1 to see the result: operator= invoked copy constructor//How did this sentence come in? Yes, the assignment operator function was invoked. But why do you call a copy constructor? Replacing the a2 = A1 in Code 1 with a functional form will help us find the answer: a2 = A1; Equivalent to a2.operator= (A1); The function operator= returns a CA object, so the compiler generates a temporary variable and invokes the copy constructor to initialize it. And then, the object is destroyed, and the destructor is invoked. Now let's add a print to the CA's construction and destructorStatement, we will see this process clearly. Class CA {Public:int *p; CA () {cout<< "constructor" <<endl;     p = NULL;};   ~ca () {    cout<< "destructor" <<endl;     delete []p;}; ...... }; Execute example code 1, the result is: constructor           //a1 Constructor constructor            //A2 Constructors operator= invoked     //assignment statements Copy constructor      //temporary variable copies constructor destructor             //Temporary variables are destructor destructor            / /A2 is destructor          //a1 created by the destructor of a temporary variable, invokes a copy constructor, and then is destructor, I wonder if you know what this means: when we call a2 = A1, A1 "owned" Memory is forwarded to A2, which is then forwarded to the temporary variable, and finally, when the temporary variable is destructor. Of course not what we want, or obediently. Define the return value type of the assignment operator function as ca& Bar.    4.      automatically created assignment operator now think, if we don't define the assignment operator in the CAWhat's going to happen, is a2 = A1 in example code 1 causing a compilation error? Of course not, the compiler will automatically create one for us. This operator behavior mimics the automatically created copy constructor: If the class contains objects (or inherited from other classes), the operator ' = ' is called recursively, which is called a member assignment. For a detailed discussion of this issue, see the first edition of the C + + programming idea, the 11th chapter (p225).  

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: info-contact@alibabacloud.com 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.