C + + Learning note 12: overload of assignment operator '='

1 Purpose: it is hoped that the types on both sides of the assignment operator can not match

    eg: assign a variable of type int to a Complex object, or assign a string of type char * to a string object.

2 assignment operator '=' can only be overloaded as a member function
3 eg: (see fuzhichongzai.cpp of the project)

/**
 * Overload example of assignment operator '='
 * */
#include <iostream>
#include <cstring>

using namespace std;

class String{
private:
    char* str;  // The private member variable str is a pointer, which is used to point to the dynamically allocated storage space. The string is placed in the dynamically allocated storage space
public:

    // Constructor new is a character array with only one element, making the storage space of pointer str pointing to new equal to char* str = new char[1];
    String()    //:str(new char[1])
    {
        str = new char[1];
        str[0] = 0; // str points to an empty string after initialization
        cout << "Call parameterless constructor" << endl;
    }

    const char* c_str()
    {
        return str;
    }

    // Overload the assignment operator. The received parameter is const char * and the return value is string&
    String& operator=(const char* s);

    // Destructor
    ~String()
    {
        cout << "Call destructor" << endl;
        delete[] str;
    }

};

String& String::operator= (const char *a) {
    // Overloading '=' enables obj = "hello" to set obj as a String object,
    delete[] str;   //Delete the memory space allocated for str member variables in the String object
    // Store for str reallocation plus 1 \ 0
    str = new char[strlen(a) + 1];
    // copy the content pointed by a pointer to the content pointed by str pointer. At this time, the content pointed by str in String object is the content pointed by A
    strcpy(str, a);
    return *this;   // Returns a reference to the String object that the modified str points to
}


int main()
{
   String s;
   s = "Good Luck,";    // Equivalent to s.operator= ("Good Luck,");
   cout << s.c_str() << endl;
   // String s2 = "hello!"; / / if this statement is not annotated, an error will occur. This statement is an initialization statement rather than an assignment statement. If the initialization statement is used, the function must be initialized with a constructor. The constructor parameter must be of type char or const char
   s = "Shenzhou 8!";   // Equivalent to s.operator = ("Shenzhen 8!");
   cout << s.c_str() << endl;
   return 0;
}

4 shallow copy and deep copy

    In the example in 3, you want to execute the following statement
    String S1, S2;
    S1 = "this";
    S2 = "that";
    S1 = S2;    // What you want to achieve is that the strings placed in S1 are the same as those placed in S2.
    //For S1 = S2; this statement can cause problems if you use a native equal sign
    //The problem is as follows
        S1  str ------> this\0      // Execute S1 = "this"; str in S1 points to this this \ 0
        S2  str ------> that\0      // Execute S2 = "that"; str in S2 points to that that \ 0
        // Execute S1 = S2; the equal sign is not overloaded at this time
        // There is no pointer to this this \ 0  storage space, which has no chance to be delete d, causing memory garbage
                        this\0
        // In S1 and S2, str points to that that \ 0  storage space
        // If S1 object dies, the destructor will release the space pointed to by S1.str, then S2 will be released once more when it dies, which is not appropriate.
        S1  str ------>
                        that\0
        S2  str ------>
    // In addition, if S1 = "other" is executed again, the place pointed by S2.str will be delete d
    //Therefore, the solution to the above problem is to add the member function string & operator = (cosnt string & S) in class String; see the example in 3.

There are also areas for improvement:

        The following statement: String s; s = "Hello";    s = s; There will be errors.
        //Improvement method:
            String& operator= (const String& s){
                // Determine whether the current object and s are the same this pointer represents an address
                if(this == &s)
                    return *this;
                delete[] str;
                str = new char[strlen(s.str) + 1];
                strcpy(str, s.str);
                return *this;
            }

Discussion on the return value of operator

        How about void?
        How about String?
        Why is string &?
        Reason: when overloading operators, good style should try to keep the original characteristics of operators
        If the overloaded operator returns void, the concatenation property a = b = c cannot be maintained because b = c returns void a = void error

        If the overloaded operator returns String, consider (a = b) = c. since in c + +, the return value of the assignment operator is the reference of the variable to the left of the equal sign, the return value of (a = b) is the reference of a to pay the reference of a to c. the effect is that the value of a is the same as the value of c, and has no relationship with B.

        Consider: a = b = c; equivalent to a.operator=(b.operator=(c));
              And (a = b) = C; will modify the value of a to be equivalent to (a.operator=(b)).operator=(c);
        In C + +, the return value of an assignment operator is a reference to the variable to the left of the equal sign

What's wrong with the String class?

        When you write a copy constructor for a String class, you will face the same problem as the non overloaded = and handle it in the same way
        String(String& s)
        {
            str = new char[strlen(s.str) + 1];
            strcpy(str, s.str);
        }
17 original articles published, praised 0, and 256 visitors
Private letter follow

Posted on Mon, 03 Feb 2020 04:52:03 -0500 by ChrisA