重载赋值运算符中需要注意的两个问题
2014-08-30 15:24
197 查看
前言
如果系统自动生成的赋值运算符重载函数不合乎你的要求,那么就应当定制自己的赋值运算符。
然而,定制赋值运算符有两点是非常值得注意的,本文将讲解这两点,让你写出更优质的 =运算符。
第一点:请返回 reference to *this
我们经常使用如 "a=b=c=1" 这种形式的连锁赋值语句,而重载的赋值运算符自然也应当能够这样使用。
因此,在重载运算符函数末尾请写上如这样的语句 return *this;
除了赋值运算符,+=,-=这样的赋值运算符同样需要这样做。
第二点:处理好自我赋值
首先,我们看一段问题代码:
问题出在重载函数中,如果左右操作数是相同的对象,delete 掉原有资源之后,所有数据信息就全丢了。
因此,运算符重载函数需要加上一个证同测试:
但这依然不是最好的做法:因为 new 有可能失败,导致资源丢失。
下面这个精心设计的重载函数才是我们需要的:
这个实现就保证了赋值的安全,健壮,是个非常可取的方案。
小结
赋值运算符还有一些其他的非常可取的实现,这里就不一一讲解了。
如果系统自动生成的赋值运算符重载函数不合乎你的要求,那么就应当定制自己的赋值运算符。
然而,定制赋值运算符有两点是非常值得注意的,本文将讲解这两点,让你写出更优质的 =运算符。
第一点:请返回 reference to *this
我们经常使用如 "a=b=c=1" 这种形式的连锁赋值语句,而重载的赋值运算符自然也应当能够这样使用。
因此,在重载运算符函数末尾请写上如这样的语句 return *this;
除了赋值运算符,+=,-=这样的赋值运算符同样需要这样做。
第二点:处理好自我赋值
首先,我们看一段问题代码:
// 位图资源类 class Bitmap { /*......*/ }; // 位图资源管理类 class Widget { public: //...... Widget & operator=(const Widget & rhs); //...... private: //...... Bitmap *pb; // 位图资源。指针类型,指向 heap 分配而得的空间 //...... }; Widget & Widget::operator=(const Widget & rhs) { delete pb; // 删除原有资源 pb = new Bitmap(*rhs.pb); // 申请新的资源并存放右操作数的数据 return *this; }
问题出在重载函数中,如果左右操作数是相同的对象,delete 掉原有资源之后,所有数据信息就全丢了。
因此,运算符重载函数需要加上一个证同测试:
Widget & Widget::operator=(const Widget & rhs) { // 加入证同测试 if (this == &rhs) return *this; delete pb; // 删除原有资源 pb = new Bitmap(*rhs.pb); // 申请新的资源 return *this; }
但这依然不是最好的做法:因为 new 有可能失败,导致资源丢失。
下面这个精心设计的重载函数才是我们需要的:
Widget & Widget::operator=(const Widget & rhs) { Bitmap * pOrig = pb; pb = new Bitmap(*rhs.pb); delete pOrig; return *this; }
这个实现就保证了赋值的安全,健壮,是个非常可取的方案。
小结
赋值运算符还有一些其他的非常可取的实现,这里就不一一讲解了。
相关文章推荐
- MySQL处理空值时你需要注意的两个问题
- C++中使用delete 需要注意的两个问题
- printf的两个需要注意的问题:无符号整数和64位整数
- 在 Hyper-V 上安装 CentOS 系统需要注意的两个问题
- 网络数据传输需要注意的两个问题
- MySQL处理空值时你需要注意的两个问题
- iOS 后台定位需要注意的两个问题
- sql server 2005笔记——将数据库从2000还原到2005需要注意的两个问题
- c++两个类相互调用需要注意的问题
- 网络数据传输需要注意的两个问题
- IBM WebSphere Portal6.1配置数据库和LDAP时需要注意的两个问题
- 编写守护脚本需要注意的的两个问题
- Tcp流套接字两个需要注意的问题:粘包和包分段
- 协程设计需要注意的两个小问题及解决
- nginx往后端转发时需要注意的两个问题
- 第九章:重载赋值运算符中需要注意的两个问题
- vector构建和销毁需要注意的两个问题
- zend_framework中需要注意的两个问题
- 如果一个页面中用了两个以上displaytag,需要注意的分页问题
- 在代码中设置ListView的divider,需要注意的两个问题