C++重载赋值运算符

重载赋值运算符

       上面我们讨论了“对象赋值异常”的问题。当对象的成员变量是指针类型时,对象之间的赋值,应该要对指针成员变量进行特殊操作。

       要解决这个问题,需要重载赋值运算符。那么,运算符的重载在后续章节深入学习。

       在这里,我们预先学习“赋值运算符重载”的知识。是为了让知识点归纳连贯起来。让读者知道,对象的赋值存在浅拷贝的问题。需要重载赋值运算符,进行深拷贝,才可以解决问题。

       所以,我们教学的方法,不是死板地列出C++的知识点,而是针对问题,分析问题,解决问题。当学习了运算符的重载之后,再回来看该章节也行。但是,我们需要知道的一个知识点是:对象赋值存在浅拷贝问题,需要重载赋值运算符,进行深拷贝。

       下面是一个测试例子,重载了赋值运算符。

程序运行结果如下:

       可以看到,使用stud对象给stud1对象赋值,当stud对象销毁之后,stud1对象的数据还是正常。因为我们增加了“重载赋值运算符”函数的定义,在该函数中,对涉及到指针类型的成员变量,进行内存申请和数据拷贝。该函数的定义如下:

    void operator = (const student& s){

        if(NULL != name){

            delete []name; //如果name已经申请内存,先释放内存;

        }

        name = new char[32]; //申请内存

        strcpy(name, s.name); //拷贝数据

        if(NULL != addr){

            delete []addr; //如果addr已经申请内存,先释放内存;

        }

        addr = new char[32]; //申请内存

        strcpy(addr, s.addr); //拷贝数据

        number = s.number;

    }

       可以看到,给对象赋值的时候,对象的name, addr是指针类型,那么,需要申请内存再拷贝数据。而且,如果name, addr成员变量不是NULL类型,可能是已经申请了内存空间,那么,我们对内存空间进行释放,再次申请新的内存空间。保证对象的指针成员变量得到合法的内存地址。

       上面的代码,我们重载了赋值运算符,满足两个对象之间的赋值。那么,如果有如下的main()函数,会产生什么结果?

int main(void){

    student stud1, stud2;

    if(1){

        student stud("wkf", "www.mylinux.vip", 13926572996);

        stud1 = stud2 = stud;

    }

    stud1.print();

    stud2.print();

    return 0;

}

       编译异常,异常信息如下:

wkf@ubuntu:~/c++$ g++ test.cpp -o exe

test.cpp: In function ‘int main()’:

test.cpp:55: error: no match for ‘operator=’ in ‘stud1 = stud2.student::operator=(((const student&)((const student*)(& stud))))’

test.cpp:36: note: candidates are: void student::operator=(const student&)

       可以看到,执行stud1 = stud2 语句的时候,出现了错误。那么,为什么会这样?

       执行 stud2 = stud; 成功,但是,执行 stud1 = stud2 语句失败?

       这个问题,当深入学习运算符重载的时候,就可以解决。解决方法就是修改重载赋值运算符,如下:

    student& operator = (const student& s){

        if(NULL != name){

            delete []name;

        }

        name = new char[32];

        strcpy(name, s.name);

        if(NULL != addr){

            delete []addr;

        }

        addr = new char[32];

        strcpy(addr, s.addr);

        number = s.number;

        return *this;

    }

       此时,编译程序,运行OK。程序分析如下:

(1) 执行stud1 = stud2 = stud;语句,分成两个步骤,先执行 stud2 = stud; 语句,把得到的返回值再赋给stud1对象。

(2) 执行 stud2 = stud; 语句的时候,调用重载的赋值运算符,相当于:

stud2.operator = (stud);

       此时,是stud2对象调用重载的赋值运算符函数,调用完之后,返回一个student对象的引用。所以,在重载赋值运算符中,赋值完之后,返回*this对象,就是返回stud2对象。

       所以,把stud2对象返回,再赋值给stud1对象;相当于stud1 = stud2; 此时,才是正确的逻辑。

韦凯峰 Linux C/C++ 程序设计教程,Linux 系统编程,Openwrt 系统开发,微信:13926572996,QQ:1523520001,博客:www.mylinux.vip

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

韦凯峰Linux编程学堂

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值