C++赋值运算符重载函数(operator=)

  由于对c++的重载符号一直不是很理解,此处参阅一些资料给出比较详细的解释,方便读者以及自己查阅。

此处有更详细的解释,但是其中关于 a = b = c执行顺序的解释不正确!

例1
#include<iostream>
#include<cstring>
using namespace std;

class MyStr
{
private:
    char *name = NULL;
    int id;
public:
    MyStr() {cout << "default\n" << endl;}
    MyStr(int _id, char *_name)   //constructor
    {
        cout << "constructor" << endl;
        id = _id;
        name = new char[strlen(_name) + 1];
        memcpy(name, _name, strlen(_name) + 1);
    }
    MyStr(const MyStr& str)
    {
        cout << "copy constructor" << endl;
        id = str.id;
        if (name != NULL)
            delete name;
        name = new char[strlen(str.name) + 1];
        memcpy(name, str.name, strlen(str.name) + 1);
    }
    MyStr& operator =(const MyStr& str)//赋值运算符
    {
        cout << "operator =" << endl;
        if (this != &str)
        {
            if (name != NULL)
                delete name;
            this->id = str.id;
            int len = strlen(str.name);
            name = new char[len + 1];
            memcpy(name, str.name, strlen(str.name) + 1);
        }
        return *this;
    }
    ~MyStr()
    {
        delete name;
    }
};

int main()
{
    MyStr str1(1, "hhxx");
    cout << "====================" << endl;
    MyStr str2;
    str2 = str1;
    cout << "====================" << endl;
    MyStr str3 = str2;
    return 0;
}
结果1
constructor
====================
default

operator =
====================
copy constructor

 此处可以看到执行

str2 = str1

时,调用了赋值运算符重载函数,可以与普通的函数调用一样理解,str2为函数调用者,str1为函数调用的参数(类似于str2.xxx(str1))。
 赋值运算符重载函数形参为引用,避免了一次对象的拷贝构造。
 同样,复制运算符重载函数函数返回值为引用,同样避免了一次对象的拷贝构造。若返回值类型为MyStr,那么在函数返回时,将构造一个linshi变量,并this指针指向的对象拷贝至该临时变量。
 当然,也可以不返回任何对象,设置返回值为void。但是,返回对象或者引用时可以实现连续赋值,类似于a = b = c,等价于a = (b = c);

例2(将返回类型改为MyStr)
#include<iostream>
#include<cstring>
using namespace std;

class MyStr
{
private:
    char *name = NULL;
    int id;
public:
    MyStr() {cout << "default\n" << endl;}
    MyStr(int _id, char *_name)   //constructor
    {
        cout << "constructor" << endl;
        id = _id;
        name = new char[strlen(_name) + 1];
        memcpy(name, _name, strlen(_name) + 1);
    }
    MyStr(const MyStr& str)
    {
        cout << "copy constructor" << endl;
        id = str.id;
        if (name != NULL)
            delete name;
        name = new char[strlen(str.name) + 1];
        memcpy(name, str.name, strlen(str.name) + 1);
    }
    MyStr operator =(const MyStr& str)//赋值运算符
    {
        cout << "operator =" << endl;
        if (this != &str)
        {
            if (name != NULL)
                delete name;
            this->id = str.id;
            int len = strlen(str.name);
            name = new char[len + 1];
            memcpy(name, str.name, strlen(str.name) + 1);
        }
        return *this;
    }
    ~MyStr()
    {
        delete name;
    }
};

int main()
{
    MyStr str1(1, "hhxx");
    cout << "====================" << endl;
    MyStr str2;
    str2 = str1;
    cout << "====================" << endl;
    MyStr str3 = str2;
    return 0;
}
结果2
constructor
====================
default

operator =
copy constructor
====================
copy constructor

 执行

str2 = str1

时,函数返回的是对象,调用拷贝构造函数产生一个临时变量。

例3(验证 a = b = c执行顺序)
#include<iostream>
#include<cstring>
using namespace std;

class MyStr
{
private:
    char *name = NULL;
    int id;
public:
    MyStr() {cout << "default\n" << endl;}
    MyStr(int _id, char *_name)   //constructor
    {
        cout << "constructor" << endl;
        id = _id;
        name = new char[strlen(_name) + 1];
        memcpy(name, _name, strlen(_name) + 1);
    }
    MyStr(const MyStr& str)
    {
        cout << "copy constructor" << endl;
        id = str.id;
        if (name != NULL)
            delete name;
        name = new char[strlen(str.name) + 1];
        memcpy(name, str.name, strlen(str.name) + 1);
    }
    MyStr& operator =(const MyStr& str)//赋值运算符
    {
    if(name != NULL)
        cout << name << " = " << str.name << endl;
        cout << "operator =" << endl;
        if (this != &str)
        {
            if (name != NULL)
                delete name;
            this->id = str.id;
            int len = strlen(str.name);
            name = new char[len + 1];
        memcpy(name, str.name, strlen(str.name) + 1);
        }
        return *this;
    }
    ~MyStr()
    {
        delete name;
    }
};

int main()
{
    MyStr str1(1, "str1");
    cout << "====================" << endl;
    MyStr str2(2, "str2"), str3(3, "str3");
    str3 = str2 = str1;
    cout << "====================" << endl;
    MyStr str4 = str2;
    return 0;
}

结果3

constructor
====================
constructor
constructor
str2 = str1
operator =
str3 = str1
operator =
====================
copy constructor

 可以看到,首先构造是三个对象,name分别为str1, str2, str3。然后执行

str3 = str2 = str1

时,先是执行str2 = str1,对象str2获取str1的name之后,str3将获取str2新获取的name。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值