C++重载赋值运算符
Posted LC编程开发者
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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
以上是关于C++重载赋值运算符的主要内容,如果未能解决你的问题,请参考以下文章