当前课程知识点:C++语言程序设计进阶 > 第八章 多态性 > 小结 > 第八章小结
主要内容
多态性的概念、运算符重载、虚函数、纯虚函数、抽象类、override 和 final
达到的目标
掌握运算符重载原理和方法
理解动态多态性的原理,掌握通过虚函数实现的多态性的方法
掌握纯虚函数和抽象类的概念和设计方法
大家好 欢迎回来继续学习C++语言程序设计
到现在为止呢 第八章我们就学习完了
首先呢 我们了解了多态性的基本概念 知道了什么是多态性
然后呢 我们通过运算符重载
又复习了一下我们曾经学过的函数重载
那么实际上 运算符重载和函数重载
都是通过静态多态性实现的
你这个函数名调用表达式跟哪个函数体去对应
那么 这个多态是通过参数表的不同来实现的
其实呢 系统预定义的这些运算符
它本身就为不同的类型 不同的基本数据类型重载过
就像我们加法 减法可以作用在整数上 也可以作用在浮点数上面
都是一样的 那实际上系统已经为不同的
基本类型重载过这些运算符了
但是当我们自定义了新类型以后
那编译器无法知道你用一个加号去作用到两个辅数上面
或者你用一个自增运算符去作用到clock类对象上面
你想达到什么目的 那当然别人没办法知道 他也没办法给你翻译
所以这时候呢 我们要自己写运算符重载函数
为我们自定义的类型去写运算符重载函数
也就是说 当我们写运算符重载函数的时候
它至少要有一个操作数 是我们自定义的类的对象
另一个操作数嘛 当然可以也是类的对象
或者呢 是基本类型的数据 都可以
那这个运算符重载函数可以重载为类的成员函数
也可以重载为类外的
非成员函数
到底怎么选择呢
有些运算符重载为成员函数或者非成员函数都可以
有些运算符呢
或者说 有些运算符
当它碰到左操作数不是对象的时候
你就只能把它重载为
非成员函数了
重载为非成员函数的时候呢
如果想提高运算效率
我们可以将这个重载函数定义为
类的友元
这样的话可以访问类的私有成员
它的运算效率就会比较高
那么这个函数
重载为非成员函数的时候 那么
左操作数就不要求必须是类的对象了
大家回去可以把这一章的例题
辅数运算那个例题呢 去扩展一下
再加几种不同的运算符重载函数的形式
比如说在类的成员函数中呢 你可以增加
辅数加实数 辅数减实数 让第二个操作数
是
基本类型的数据
不是复数
然后在重载为类外的非成员函数的时候呢
你可以让第一个操作数
是实数
实现实数加复数
实数减复数
大家可以回去试一试 然后这个自增自减运算符呢
我们看到了例题中呢 是在clock类里面实现了对象的自增一秒
包括它前置的++和后置的++
通过这个我们了解了后置++原来如此啊
终于大家明白了 是在加一之前就把原来那个数的副本存起来了
然后在运算中呢 用的是那个加一之前的那个副本
而
自己对象呢悄悄的加了一
实际上就这么一个意思
大家也可以 定义一些其他的类
试试你为它重载一下后置的单目运算符
在这一章呢 其实重点是学习它的动态多态性
动态多态性呢
我们简单的了解了一下它的原理
其实就是通过这个虚表来实现的
在每个具有虚函数的类里面呢
都有一个虚表
里面有指向各个虚函数函数体的
这个接口啊这个入口
而 具有虚函数的类 它的对象
除了我们显式定义的数据成员以外
都会有一个多出来的隐含的成员
就是指向虚表的指针
通过这个指向虚表的指针
在运行的时候呢
我们就可以通过这个指针找到它应该调用的那个函数的函数体
于是呢
我们就可以在类的定义的时候
在类体里面声明某些函数
它是虚函数 那就是告诉编译器
这个函数的调用表达式
你都不要在编译阶段去确定它对应哪个函数体
相反 你应该把这样的虚函数的函数体的入口放在这个类的虚表里面
那么 运行时 让他自己去识别 去找到这个函数体
所以呢 这就是我们实现多态性和动态绑定的这个虚函数
在基类中定义了虚函数以后
派生类继承过来
自动也就成为了虚函数
但是建议大家在派生类中
把这个virtual关键字也要写上
这样程序的可读性就会比较好
当我们定一个概念比较抽象的类的时候呢
其中有些函数可能由于信息不够具体算法无法实现
那么这个时候呢
可以把它定义为 纯虚函数
就是没有函数体
具有纯虚函数的类呢就叫做抽象类 那抽象类
它是不能定义实体的
不能实例化 不能定义对象的
它的作用就是
当别的类的基类
用来规范整个类家族的统一的对外接口和必须具有的功能
那么用这样的机制呢
我们就可以编写尽量通用的程序了
最后呢 我们还学习了c++11的
新的功能override和final
都是非常有用的
那这一章结束之后呢 希望大家多编程序 多实践
-导学
--导学
-继承的基本概念和语法
-第七章 继承与派生--继承的基本概念和语法习题
-继承方式
-第七章 继承与派生--继承方式
-基类与派生类类型转换
-第七章 继承与派生--基类与派生类类型转换
-派生类的构造和析构
--派生类的构造函数
--派生类的析构函数
--第七章 继承与派生--派生类的构造和析构
-派生类成员的标识与访问
--虚基类
-第七章 继承与派生--派生类成员的标识与访问
-小结
--小结
-综合实例
--第七章综合实例
-实验七
--实验七
-导学
--导学
-第八章 多态性--导学
-运算符重载
--运算符重载的规则
-第八章 多态性--运算符重载
-虚函数
--虚函数
--虚析构函数
--虚表与动态绑定
-第八章 多态性--虚函数
-抽象类
--抽象类
--第八章 多态性--抽象类
-override与final
-第八章 多态性--override与final
-小结
--第八章小结
-综合实例
--第八章综合实例
-实验八
--实验八
- 第八章讲义
-导学
--导学
-模板
--函数模板
--类模板
-第九章 模板与群体数据--模板
-线性群体
--线性群体的概念
-第九章 模板与群体数据--线性群体
-数组
--数组类模板
-链表
--链表类模板
-第九章 模板与群体数据--链表
-栈
--栈类模板
--栈类模板课后习题
--例9-9 栈的应用课后习题
-队列
--队列类模板
-第九章 模板与群体数据--队列
-排序
--排序概述
--插入排序
--选择排序
--交换排序
-第九章 模板与群体数据--排序
-查找
--查找
--查找课后习题
-小结
--小结
-综合实例
--综合实例
-实验九
--实验九
- 第九章讲义
-导学
--导学
-泛型程序设计及STL的结构
--STL简介
-第十章 泛型程序设计与C++标准模板库--泛型程序设计及STL的结构
-迭代器
--迭代器
-第十章 泛型程序设计与C++标准模板库--迭代器
-容器的基本功能与分类
-第十章 泛型程序设计与C++标准模板库--容器的基本功能与分类
-顺序容器
--顺序容器的特征
--第十章 泛型程序设计与C++标准模板库--顺序容器
-关联容器
--集合
--映射
-第十章 泛型程序设计与C++标准模板库--关联容器
-函数对象
--函数对象
--函数适配器
-算法
--算法
-小结
--第十章小结
-综合实例
--综合实例
-实验十
--实验十
- 第十章讲义
-导学
--导学
-I/O流的概念及流类库结构
-第十一章 流类库与输入/输出--I/O流的概念及流类库结构
-输出流
--输出流概述
--向文本文件输出
--向二进制文件输出
--向字符串输出
-第十一章 流类库与输入/输出--输出流
-输入流
--输入流概述
--输入流应用举例
--从字符串输入
-第十一章 流类库与输入/输出--输入流
-输入/输出流
--输入/输出流
-第十一章 流类库与输入/输出--输入/输出流
-小结
--小结
-综合实例
--综合实例
-实验十一
--实验十一
- 第十一章讲义
-导学
--第12章导学
-异常处理的思想与程序实现
-第十二章 异常处理--异常处理的思想与程序实现
-异常处理中的构造与析构
-第十二章 异常处理--异常处理中的构造与析构
-标准程序库异常处理
-第十二章 异常处理--标准程序库异常处理
-小结
--第12章小结
-综合实例
--综合实例
-实验十二
--实验十二
- 第十二章讲义