C++运算符重载(3) - 什么时候需要自定义赋值操作符
来源:互联网 发布:淘宝宝贝介绍图片尺寸 编辑:程序博客网 时间:2024/06/05 18:37
答案与拷贝构造函数一样。如果一个类不包含指针,则不需要自定义赋值操作符与拷贝构造函数。编译器会给每个类创建一个默认的拷贝构造函数和默认的赋值操作符。但是,当类中包含有指针或任何运行时分配的资源时,编译器生成的这两个函数,可能会失效。
参考下面程序:
#include<iostream>using namespace std; // 没有自定义赋值操作符class Test{ int *ptr;public: Test (int i = 0) { ptr = new int(i); } void setValue (int i) { *ptr = i; } void print() { cout << *ptr << endl; }}; int main(){ Test t1(5); Test t2; t2 = t1; t1.setValue(10); t2.print(); return 0;}上面程序输出结果为: 10
仔细看下main函数,会发现使用setValue()修改了t1的值后,对象t2也跟着改变了。这会导致未知的行为。
因为上面程序没有自定义赋值操作符,所以编译器生成了一个默认的,会将'ptr‘从右侧拷贝到左侧。所以两个对象中的ptr指向相同位置。
因为上面程序没有自定义赋值操作符,所以编译器生成了一个默认的,会将'ptr‘从右侧拷贝到左侧。所以两个对象中的ptr指向相同位置。
可以使用两种方法来解决上面问题:
1) 禁止对象之间进行赋值操作。我们可以使用自定义的赋值运算符并定义为private.
2) 自定义赋值运算符来实现深拷贝(deep copy).
对于拷贝构造函数,也是同样的道理。
1) 禁止对象之间进行赋值操作。我们可以使用自定义的赋值运算符并定义为private.
2) 自定义赋值运算符来实现深拷贝(deep copy).
对于拷贝构造函数,也是同样的道理。
下面是重载了赋值运算符后的程序:
#include<iostream>using namespace std; class Test{ int *ptr;public: Test (int i = 0) { ptr = new int(i); } void setValue (int i) { *ptr = i; } void print() { cout << *ptr << endl; } Test & operator = (const Test &t);}; Test & Test::operator = (const Test &t){ //检测是否为自己 if(this != &t) *ptr = *(t.ptr); return *this;}int main(){ Test t1(5); Test t2; t2 = t1; t1.setValue(10); t2.print(); return 0;}运行结果:
5
我们应该同时给上面程序加入拷贝构造函数,运行类似这样的语句时“Test t3 = t4;” 不会出现未知行为。
注意赋值操作符中的if条件判断。当重载赋值操作符时,必须要检查自我赋值。否则,一个对象赋值给它自己,可能会导致未知的行为。在上面程序中,不一定需要自我赋值检查,因为ptr总是指向一个整数,可以重用相同内存。但是总体来说,检查自我赋值是一个好的编程实践方法。
0 0
- C++运算符重载(3) - 什么时候需要自定义赋值操作符
- C++ 操作符重载(3) 什么时候需要自定义赋值操作符
- 什么时候需要重载拷贝构造函数(赋值运算符)!
- C++:赋值运算符重载
- 重载赋值运算符(c/c++)
- 赋值运算符和操作符重载
- 重载赋值运算符(c++)
- 重载赋值运算符
- 重载赋值运算符
- 重载赋值运算符
- 重载赋值运算符
- 重载赋值运算符
- 重载赋值运算符
- 赋值运算符重载
- 赋值运算符重载
- 重载赋值运算符
- 重载赋值运算符
- 赋值运算符重载
- 总结了近百个Android优秀开源项目,覆盖Android开发的每个角落
- Activity启动模式/加载模式
- SpringAOP功能自我调用的解决方案
- ANDROID STRINGS.XML的特殊字符_安卓STRING.XML添加空格或字符的方法
- strcpy、memcpy和memset的区别
- C++运算符重载(3) - 什么时候需要自定义赋值操作符
- 获取数据库所有列以及列的类型是否为空是否为默认值是否为主键
- iOS开发系列--iOS应用架构谈
- ACM-日期计算
- 排序算法总结
- PDF转换成Word的制作方法
- 清迈中文离线地图App上线
- 创始人之间应该如何量化分配股权?
- 关于spring Entity 在不同包下的无法扫描的解决方案