当前课程知识点:C++语言程序设计进阶 >  第八章 多态性 >  运算符重载 >  单目运算符重载为成员函数

返回《C++语言程序设计进阶》慕课在线视频课程列表

单目运算符重载为成员函数在线视频

单目运算符重载为成员函数

前置单目运算符重载规则

后置单目运算符 ++和--重载规则

例8-2重载前置++和后置++为时钟类成员函数



下一节:运算符重载为非成员函数

返回《C++语言程序设计进阶》慕课在线视频列表

单目运算符重载为成员函数课程教案、知识点、字幕

大家好

欢迎回来继续学习

C++语言程序设计

接下来呢

我们再来看看单目运算符

怎么重载

还有这个前置++

后置++怎么区分呢

那么如果我们要重载一个

单目运算符

比如说我们用代号U表示

某种单目运算符

需要将这样的单目运算符

重载为类的成员函数

那它又分前置单目运算符

和后置单目运算符

首先呢

我们来看

前置单目运算符的重载规则

那么前置单目运算符

它要实现的表达式呢

就是运算符在前

操作数在后

比如说

我们这里用U oprd

来代表

其中这个oprd是A类的对象

那么这个时候

我们可以将U

重载为A类的成员函数

这个时候呢

是不需要形参的

因为只有一个操作数

这个操作数就是类的对象

这个时候如果我们去

在程序中写U oprd

这样的表达式

就相当于通过oprd这个对象

去调用operatorU这个函数

那么如果我们要为后置的++

和--

重载运算符函数

它与前置++ - -的运算符函数

差别在哪儿呢

我们知道

如果说两个函数的名字相同

要能够区分它们的话

那只能用参数表来区分了

因为不管前置++ 后置++

它的运算符都是两个+号

那么这就决定了

它的重载函数名

都必须是operator++

也就说函数名是一样的了

这个时候要区分哪个是前置的

哪个是后置的

当然只能通过参数表

所以呢

后置的自增自减运算符

它的重载函数的参数表

里面的参数

要比前置的多一个参数

而多的这个参数呢

就只用来区分

它是一种不同的重载形式

在函数体中是不能使用它的

所以当我们在程序中

出现了后置++的

这种表达式的时候

就相当于通过对象

去调用operator++函数

但是实参给了它一个整数0

下面这个例子呢

就通过时钟类来演示了

如何将前置++和后置++

都重载为时钟类的成员函数

前置的单目运算符重载的时候

函数是没有形参的

这个我们刚刚知道了

而后置的运算符呢

重载函数

需要有一个int类型的形参

那么在这道例题中呢

操作数就是时钟类的对象

clock类的对象

时间的功能不管是前置++

还是后置++

我们都要求它实现

时间加1秒钟的功能

我记得大家在一开始

学习基本的算术运算的时候

有很多同学

一直存下了一个疑惑

这个前置++和后置++

它到底是怎么实现的这个差别呢

而且有的同学可能甚至就

到底也弄不清楚

它到底差别在哪儿

通过这个例题

通过我们自己写一个函数

来分别实现前置++

写另一个函数实现后置++

这样呢

我们就会彻底地明白

到底这两者实现上

有什么不同

现在我们来看一下

这个例题的原代码

现在我们在时钟类中

重载了两个自增运算符函数

第一个是前置自增的运算符

所以呢

它是参数表中是没有参数的

因为是单目前置运算符

那第二个是后置++运算符

为了区分前置与后置

那么它们的参数表必须不同

所以语法上规定

当重载后置自增运算符的时候

参数表里面

要有一个int类型的参数

但是这个参数

它的目的只是为了区分

它是一个后置的运算符

那么在实现的时候

函数体中

是不应该去使用这个参数的

好 那这个钟表类的定义呢

我们回顾一下

首先它的构造函数中

要判断数据的合法性

然后呢

用参数值去初始化

当前对象的数据成员

然后showTime显示时间

现在看我们刚刚增加的

这个运算符重载函数

先看前置自增运算符

它实现加1秒的功能

那么时间加1秒以后呢

要判断是不是秒数大于等于60了

如果是的话呢

秒数减掉60分加1

如果分钟大于等于60分钟了

那么这么

minute就减60

然后小时数加1

因为用的是24小时制

所以小时数加1以后

还要对24取余

那最后呢

返回当前对象

那么这个前置自增呢

它的运算结果

也就是它的函数的返回值

应该是一个本类对象的引用

也就是说

它返回的是个左值

我们知道前置自增是先增1

后使用

所以使用的就是它返回的那个值

当然得返回它自己

所以应该是个引用

那么再看这个后置加1

后置加1呢

我们说是先使用后加1

这是一个

不太准确的形象的说法

在第二章中

我们讲前置 后置

自增自减运算符的时候呢

这样简单地解释

大家可能心里还有些疑问

什么叫先加1后使用

什么叫先使用后加1呢

到底是怎么实现的呢

肯定做这个自增运算符的时候

它都加1了

那现在我们来看

我们自己写一个实现

后置自增运算的函数

大家就清楚了

那么现在呢

我们要首先将当前对象目前的值

也就是*this

当前对象目前的值

暂时存储在

一个临时的局部变量里面

这个old

然后对当前对象实行加1的运算

那么这个加1

当然我们把上面这段程序

拷贝过来

但是这个不是好办法

比较好的办法就是说

我们直接调用这个前置自增运算符

这样的话呢

都是加1

两边的算法就能够统一了

如果你两个函数体都是单独写的

那么它的算法有可能

在几经修改以后

就变得不一致了

比如说

现在我们使用24小时制的

你可以把代码复制过来

可是后面经过修改

可能想改成12小时制

但是这两处有一处忘了改

那么它就实现功能的方式

就不一致了

所以为了避免这种情况呢

我们比较好的方案就是

让这个后置自增运算

直接调用这个

前置的自增运算函数

所以将当前对象前置++自增1

然后

这个函数的返回结果是什么呢

关键在这儿

返回的结果呢

是刚才存起来的这个

原来没有加1的时间

存在old里面了

将old返回

所以现在我们看到

这两个函数的差别吧

这个返回的是加1以后的那个数

所以呢

这个返回值

再继续参与其他更复杂范围

更大范围的运算的时候

用的是加1以后的那个值

而这个函数返回的是

没有加1的那个旧的值

所以它再去参与

更大范围的运算的时候呢

用的是那个没有加1的旧的值

但是其实这时候

它自己已经暗地里加了1了

这就是前置加1和后置加1

它实现上的差别

现在大家可以理解

一个前置自增运算符

我们说它先加1再使用

那么后置自增运算符

它先使用加1

其实这个说法不是很确切

其实使用的时候

它已经被加1了

只不过使用的是

它没加1之前

就复制出来的那个副本

所以实现的原理是这样的

还有呢

由于这个后置+1

它使用的是

这个对象的一个副本

而不是这个对象自己

所以它返回的是一个右值

所谓右值就是通过这个值

你是不能去改变这个对象的

因为它返回的就是一个复制品

你通过这个复制品

你用这个值没有问题

你触及不到这个对象本身

而前置++呢

它返回的就是对象本身

那么返回值

是当前对象的这个引用

所以通过这个引用

你可以直接操纵这个对象的

所以这是前置++和后置++

它的另一个不同点

就是它的运算结果

前置的它是一个左值

后置的自增

它的运算结果是一个右值

实际上

就是它原来对象的一个副本

现在呢

我们来看在主函数中验证一下

构造了一个时钟类对象

把时间初始化在23点59分59秒

然后我们显示一下这个时间

在这儿调用showTime显示一下

接下来呢

就调用后置自增运算

实际上就调用了这个operator

后置自增这个函数

调用完了以后

大家看这个返回的结果

就应该放在这个括号里面了

通过这个返回的结果

去调用showTime

而这个返回结果

是myClock自己吗

绝对不是

我们看到返回的结果

是myClock自己的一个副本

所以通过这个临时的副本

调用showTime

看到的时间是什么呢

是它还没有加1之前的时间

因为它还没有加1之前的时间

放在旁边存着

然后把这个副本返回了

它自己加1了

但是并没有把加1的这个值返回

所以呢

我们在这里看到的

是没有加1之前的这个数据

接下来呢

我们再调用前置++运算

那么这回呢

基础是什么

基础是

这个原来的23点59分59秒

已经经过后置++增了1秒

变成0点0分0秒了

在这个基础上再加1

而且返回的

就是加1以后的这个结果

所以两次加1的效果

都反映在这次输出里面了

我们看到输出的是0点0分1秒

因为它返回的

是加1以后的自己

所以通过这个例题

我想大家不仅学会了

编写前置自增

后置自增的这个运算符重载函数

也对前置和后置的运算符

有了更清楚地理解

C++语言程序设计进阶课程列表:

第七章 继承与派生

-导学

--导学

-继承的基本概念和语法

--继承的基本概念和语法

-第七章 继承与派生--继承的基本概念和语法习题

-继承方式

--继承方式简介及公有继承

--私有继承和保护继承

-第七章 继承与派生--继承方式

-基类与派生类类型转换

--基类与派生类类型转换

-第七章 继承与派生--基类与派生类类型转换

-派生类的构造和析构

--派生类的构造函数

--派生类的构造函数举例

--派生类的复制构造函数

--派生类的析构函数

--第七章 继承与派生--派生类的构造和析构

-派生类成员的标识与访问

--访问从基类继承的成员

--虚基类

-第七章 继承与派生--派生类成员的标识与访问

-小结

--小结

-综合实例

--第七章综合实例

-实验七

--实验七

-第七章讲义

第八章 多态性

-导学

--导学

-第八章 多态性--导学

-运算符重载

--运算符重载的规则

--双目运算符重载为成员函数

--单目运算符重载为成员函数

--运算符重载为非成员函数

-第八章 多态性--运算符重载

-虚函数

--虚函数

--虚析构函数

--虚表与动态绑定

-第八章 多态性--虚函数

-抽象类

--抽象类

--第八章 多态性--抽象类

-override与final

--override与final

-第八章 多态性--override与final

-小结

--第八章小结

-综合实例

--第八章综合实例

-实验八

--实验八

- 第八章讲义

第九章 模板与群体数据

-导学

--导学

-模板

--函数模板

--类模板

-第九章 模板与群体数据--模板

-线性群体

--线性群体的概念

-第九章 模板与群体数据--线性群体

-数组

--数组类模板

--例9-4数组类应用举例

-链表

--链表的概念与结点类模板

--链表类模板

-第九章 模板与群体数据--链表

-栈

--栈类模板

--栈类模板课后习题

--例9-9 栈的应用

--例9-9 栈的应用课后习题

-队列

--队列类模板

-第九章 模板与群体数据--队列

-排序

--排序概述

--插入排序

--选择排序

--交换排序

-第九章 模板与群体数据--排序

-查找

--查找

--查找课后习题

-小结

--小结

-综合实例

--综合实例

-实验九

--实验九

- 第九章讲义

第十章 泛型程序设计与C++标准模板库

-导学

--导学

-泛型程序设计及STL的结构

--泛型程序设计的基本概念

--STL简介

-第十章 泛型程序设计与C++标准模板库--泛型程序设计及STL的结构

-迭代器

--迭代器

-第十章 泛型程序设计与C++标准模板库--迭代器

-容器的基本功能与分类

--容器的基本功能与分类

-第十章 泛型程序设计与C++标准模板库--容器的基本功能与分类

-顺序容器

--顺序容器的基本功能

--顺序容器的特征

--顺序容器的插入迭代器与适配器

--第十章 泛型程序设计与C++标准模板库--顺序容器

-关联容器

--关联容器分类和基本功能

--集合

--映射

--多重集合和多重映射

-第十章 泛型程序设计与C++标准模板库--关联容器

-函数对象

--函数对象

--函数适配器

-算法

--算法

-小结

--第十章小结

-综合实例

--综合实例

-实验十

--实验十

- 第十章讲义

第十一章 流类库与输入/输出

-导学

--导学

-I/O流的概念及流类库结构

--I/O流的概念及流类库结构

-第十一章 流类库与输入/输出--I/O流的概念及流类库结构

-输出流

--输出流概述

--向文本文件输出

--向二进制文件输出

--向字符串输出

-第十一章 流类库与输入/输出--输出流

-输入流

--输入流概述

--输入流应用举例

--从字符串输入

-第十一章 流类库与输入/输出--输入流

-输入/输出流

--输入/输出流

-第十一章 流类库与输入/输出--输入/输出流

-小结

--小结

-综合实例

--综合实例

-实验十一

--实验十一

- 第十一章讲义

第十二章 异常处理

-导学

--第12章导学

-异常处理的思想与程序实现

--异常处理的思想与程序实现

-第十二章 异常处理--异常处理的思想与程序实现

-异常处理中的构造与析构

--异常处理中的构造与析构

-第十二章 异常处理--异常处理中的构造与析构

-标准程序库异常处理

--标准程序库异常处理

-第十二章 异常处理--标准程序库异常处理

-小结

--第12章小结

-综合实例

--综合实例

-实验十二

--实验十二

- 第十二章讲义

单目运算符重载为成员函数笔记与讨论

也许你还感兴趣的课程:

© 柠檬大学-慕课导航 课程版权归原始院校所有,
本网站仅通过互联网进行慕课课程索引,不提供在线课程学习和视频,请同学们点击报名到课程提供网站进行学习。