第九章:重载赋值运算符中需要注意的两个问题

前言

如果系统自动生成的赋值运算符重载函数不合乎你的要求,那么就应当定制自己的赋值运算符。

然而,定制赋值运算符有两点是非常值得注意的,本文将讲解这两点,让你写出更优质的 =运算符。

第一点:请返回 reference to *this

我们经常使用如 "a=b=c=1" 这种形式的连锁赋值语句,而重载的赋值运算符自然也应当能够这样使用。

因此,在重载运算符函数末尾请写上如这样的语句 return *this;

除了赋值运算符,+=,-=这样的赋值运算符同样需要这样做。

第二点:处理好自我赋值

首先,我们看一段问题代码:

 1 // 位图资源类
 2 class Bitmap { /*......*/ };
 3
 4 // 位图资源管理类
 5 class Widget {
 6 public:
 7     //......
 8     Widget & operator=(const Widget & rhs);
 9     //......
10 private:
11     //......
12     Bitmap *pb;    // 位图资源。指针类型,指向 heap 分配而得的空间
13     //......
14 };
15
16 Widget & Widget::operator=(const Widget & rhs)
17 {
18     delete pb;    // 删除原有资源
19     pb = new Bitmap(*rhs.pb);    // 申请新的资源并存放右操作数的数据
20     return *this;
21 }

问题出在重载函数中,如果左右操作数是相同的对象,delete 掉原有资源之后,所有数据信息就全丢了。

因此,运算符重载函数需要加上一个证同测试:

 1 Widget & Widget::operator=(const Widget & rhs)
 2 {
 3     // 加入证同测试
 4     if (this == &rhs)
 5         return *this;
 6
 7     delete pb;    // 删除原有资源
 8     pb = new Bitmap(*rhs.pb);    // 申请新的资源
 9
10     return *this;
11 }

但这依然不是最好的做法:因为 new 有可能失败,导致资源丢失。

下面这个精心设计的重载函数才是我们需要的:

1 Widget & Widget::operator=(const Widget & rhs)
2 {
3     Bitmap * pOrig = pb;
4     pb = new Bitmap(*rhs.pb);
5     delete pOrig;
6
7     return *this;
8 }

这个实现就保证了赋值的安全,健壮,是个非常可取的方案。

小结

赋值运算符还有一些其他的非常可取的实现,这里就不一一讲解了。

时间: 2024-08-04 16:17:27

第九章:重载赋值运算符中需要注意的两个问题的相关文章

重载赋值运算符中需要注意的两个问题

前言 如果系统自动生成的赋值运算符重载函数不合乎你的要求,那么就应当定制自己的赋值运算符. 然而,定制赋值运算符有两点是非常值得注意的,本文将讲解这两点,让你写出更优质的 =运算符. 第一点:请返回 reference to *this 我们经常使用如 "a=b=c=1" 这种形式的连锁赋值语句,而重载的赋值运算符自然也应当能够这样使用. 因此,在重载运算符函数末尾请写上如这样的语句 return *this; 除了赋值运算符,+=,-=这样的赋值运算符同样需要这样做. 第二点:处理好

CentOS7安装CDH 第九章:CDH中安装Kafka

相关文章链接 1. CDH官网Kafka的安装教程网址 https://www.cloudera.com/documentation/kafka/latest/topics/kafka_installing.html#concept_m2t_d45_4r 2. 下载对应的Kafka版本 1.查看CDH和Kafka的版本对应列表: 查看网址:https://www.cloudera.com/documentation/enterprise/release-notes/topics/rn_conso

第九章 C语言在嵌入式中的应用

上章回顾 编码的规范和程序版式 版权管理和申明 头文件结构和作用 程序命名 程序注释和代码布局规范 assert断言函数的应用 与0或NULL值的比较 内存的分配和释放细节,避免内存泄露 常量特性 [email protected]:Kevin-Dfg/[email protected]:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.git 第九章 第九章 C语言在嵌入式中的应用 C语言在嵌入式中的应用 [email protecte

c++第九章-(运算符重载)

一些规则 1.c++不允许用户自己定义新的运算符,只能对已有的c++运算符进行重载. 2.除了五个运算符不允许重载外,其他运算符允许重载: .成员访问运算符 *成员指针访问运算符 ::与运算符 sizeof尺寸运算符 ?:条件运算符 3.重载运算符必须和用户定义的自定义类型的对象一起使用.(也就是说,参数不能全部都是c++的标准类型,这样约定是为了防止用户修改用于标准类型结构的运算符性质) 4.为什么运算符重载函数有两个参数,只需有一个参数? 其实是有一个参数是隐含着的,运算符函数是用this指

c++ primer 5th 笔记:第九章

第九章:顺序容器 笔记 1. 一个容器就是一些特定类型对象的集合.顺序容器(sequential container)为程序员提供了控制元素存储和访问顺序的能力. 2. 容器分为有序容器和无序容器:访问分为顺序访问和随机访问. 3. forward_list和array是新C++标准增加的类型.与内置数组相比,array是一种更安全.更容易使用的数组类型.与内置数组类似,array对象的大小是固定的. 4. 通常,使用vector是最好的选择,除非你有很好的理由选择其他容器. 5. 容器操作中类

第九章 多语言环境的支持和多屏幕的适配(1)

第九章 多语言环境的支持和多屏幕的适配 资源是在代码中使用到的,并且在编译时被打包进应用程序的附加文件.出于加载效率的考虑,资源被从代码中分离出来,而且XML文件被编译进二进制代码中.在Android中,程序代码可以不直接和资源发生关系,而是通过R文件提供的索引来间接的引用某一个资源.Android系统会自动根据用户当前的环境,和屏幕分辨率情况,自动选用最合适的资源.正是基于Android系统这种独特的处理方式,开发者可以编写多套资源文件,从而很方便的实现多语言环境的支持和多种屏幕的适配. 本章

javascript高级程序设计 第九章-- 客户端检测

javascript高级程序设计 第九章-- 客户端检测 客户端检测是javascript开发中最具争议的一个话题,由于浏览器间存在差别,通常需要根据不同浏览器的能力分别编写不同的代码.有下列常使用的客户端检测方法:能力检测:在编写代码之前先检测特定浏览器的能力.例如,脚本在调用某个函数之前,可能要先检测该函数是否存在.这种检测方法将开发人员从考虑具体的浏览器类型和版本中解放出来,让他们把注意力集中到相应的能力是否存在上.能力检测无法精确地检测特定的浏览器和版本.怪癖检测:怪癖实际上是浏览器中存

zabbix专题:第九章 自定义key(案例:监控内存,监控nginx状态)

第九章 自定义key 对Linux有兴趣的朋友加入QQ群:476794643 在线交流 本文防盗链:http://zhang789.blog.51cto.com 为什么要自定义KEY 有时候我们想让被监控端执行一个zabbix没有预定义的检测,zabbix的用户自定义参数功能提供了这个方法.我们可以在客户端配置文件zabbix_angentd.conf里面配置UserParameter. 语法如下: UserParameter=key,command 用户自定义参数包含一个key和一个命令,ke

读书笔记第九章

第九章HAL是建立在linux驱动之上的一套程序库.这套程序库并不属于linux内核,而是属于linux内核层之上的应用层.可以用来保护不想公开源代码的作者.HAL架构比较简单,其基本原理就是在安卓系统中使用程序库调用位于内核空间的linux驱动,然后安卓应用程序可以通过NDK程序访问HAL中的程序库,或直接在安卓应用程序中访问HAL中的程序库.编写一款支持HAL的linux驱动程序的步骤:1.编写linux驱动,linux驱动的代码要尽量简介,尽可能将业务逻辑放到HAL library中.2.