C + + assignment operator overload [C + +] (v)

Posted by violinrocker on Sat, 22 Feb 2020 13:30:17 +0100

Assignment operator overload

Explain

Assignment operator overload is to assign a value to another object with an existing object. After both objects have been created, assignment occurs.

grammar

Fixed format
 Class name
{ 
Class name & operator = (const class name & source object) 
Copy body 
}


class A 
{ 
A& operator=(const A& another) 
{ 
/ / function body 
return *this; 
} 
}
; 

Characteristic

#include <iostream>
using namespace std;

struct Data
{
public:
    Data(int y = 2016, int m = 6, int d = 6)
        :year(y), month(m), day(d), space(new char[1024])
    {}
    
    void dis()
    {
        cout << " year " << year << " month " << month << " day " << day << endl;
    }
private:
    int year;
    int month;
    int day;
    char* space;
};

int main()
{
    Data d(2018, 8, 8);   
    d.dis();
    Data d2(2019, 9, 9);
    d2 = d;
    d2.dis();
    return 0;
}

We can see that the two printouts are the same:

We can see that we didn't write assignment operator overload ourselves, but we did succeed in assignment and assigned correctly. We will explain here. The system provides default assignment operator overload. It is also a kind of shallow assignment behavior. We need to understand the difference between copy constructor and assignment operator overload. Copy constructor does not exist in the past and directly copies one copy. Assignment operator overload has two copies. Then take the first copy and overwrite the second copy.

If there is no heap memory space in the object, it can meet the requirements by default.
Fixed format syntax

Once self implemented, the default will not exist

If we implement it but there is no content in it, we cannot copy it:

#include <iostream>
using namespace std;

struct Data
{
public:
    Data(int y = 2016, int m = 6, int d = 6)
        :year(y), month(m), day(d), space(new char[1024])
    {}
    Data& operator = (const Data& another)
    {
    }
    void dis()
    {
        cout << " year " << year << " month " << month << " day " << day << endl;
    }
private:
    int year;
    int month;
    int day;
    char* space;
};

int main()
{
    Data d(2018, 8, 8);   
    d.dis();
    Data d2(2019, 9, 9);
    d2 = d;
    d2.dis();
    return 0;
}

The operation result is:

We can see that there is no overload success.

Then we implement operator overloading by ourselves:

#include <iostream>
using namespace std;

struct Data
{
public:
    Data(int y = 2016, int m = 6, int d = 6)
        :year(y), month(m), day(d), space(new char[1024])
    {}
    Data& operator = (const Data& another)
    {
        this->year = another.year;
        this->month = another.month;
        this->day = another.day;
        return *this;
    }
    void dis()
    {
        cout << " year " << year << " month " << month << " day " << day << endl;
    }
private:
    int year;
    int month;
    int day;
    char* space;
};

int main()
{
    Data d(2018, 8, 8);   
    d.dis();
    Data d2(2019, 9, 9);
    d2 = d;
    d2.dis();
    return 0;
}

The operation result is:

We can see that the operator overloading implemented in the above example is the same as that provided by the system.

Let's explain why return * this is added to operator duplication:
We only give the code in the main function, other codes remain the same:

int main()
{
    Data d(2018, 8, 8);   
    d.dis();
    Data d2(2019, 9, 9);
    d2 = d;
    d2.dis();
    //Use to return this pointer
    Data d3;
    d3 = d2 = d;     //It is not the same as the following line of code
    d3.operator=(d2.operator=(d));
    return 0;
}

The above meaning is: d is assigned to d2, the whole expression returns d2, and d2 is passed as a parameter, and d2 is assigned to d3.

Problems in self realization

Reanalysis

Then, when memory is released, there will be a problem of repartition.

Memory leak

Solution: first release the previous memory, and then make a deep copy.

Self assignment

Self assignment means that when self assignment occurs, the original memory space is released, but the original memory space is still its own. If it is released, the assignment operator cannot be overloaded, so we need to solve this problem in self implementation.

Solve

Code implementation:

#include <string.h>
#include <iostream>
using namespace std;

struct Data
{
public:
    Data(int y = 2016, int m = 6, int d = 6)
        :year(y), month(m), day(d), space(new char[1024])
    {}
    Data& operator = (const Data& another)
    {
        if (this == &another)   //Solve the problem of self assignment
            return *this;         //Realize chain expression
        else
        {
            delete[]this->space;    //Resolve memory leaks
            space = new char [strlen(another.space) + 1];
            strcpy(space, another.space);
        }
    }

    ~Data()        //Solve the problem of reanalysis
    {
        cout << "~~~~~~~~" << this << endl;  //Pointer to the current object
        delete[]space;
    }
    void dis()
    {
        cout << " year " << year << " month " << month << " day " << day << endl;
    }
private:
    int year;
    int month;
    int day;
    char* space;
};

int main()
{
    Data d(2018, 8, 8);   
    d.dis();
    Data d2(2019, 9, 9);
    d2 = d;
    d2.dis();
    return 0;
}

The above self implementation code solves these three problems.

Next we show that we are
Data & operator = (const Data& another)
During the delivery, the content is const, which means that the content in another will not be modified
Data& operator = (const Data& another)
There is no reference at the front, so you can return the content of this pointer. If you add the
const Data& operator = (const Data& another)
We can see that if const is used outside the reference, it can be assigned. If you don't want to be assigned, you can add const in the front.
For example: (d3 = d2) = d; if there is const before it, the expression cannot be assigned.

125 original articles published, 73 praised, 10000 visitors+
Private letter follow