大家好 欢迎回来继续学习C++语言程序设计
到现在为止呢 第八章我们就学习完了
首先呢 我们了解了多态性的基本概念 知道了什么是多态性
然后呢 我们通过运算符重载
又复习了一下我们曾经学过的函数重载
那么实际上 运算符重载和函数重载
都是通过静态多态性实现的
你这个函数名调用表达式跟哪个函数体去对应
那么 这个多态是通过参数表的不同来实现的
其实呢 系统预定义的这些运算符
它本身就为不同的类型 不同的基本数据类型重载过
就像我们加法 减法可以作用在整数上 也可以作用在浮点数上面
都是一样的 那实际上系统已经为不同的
基本类型重载过这些运算符了
但是当我们自定义了新类型以后
那编译器无法知道你用一个加号去作用到两个辅数上面
或者你用一个自增运算符去作用到clock类对象上面
你想达到什么目的 那当然别人没办法知道 他也没办法给你翻译
所以这时候呢 我们要自己写运算符重载函数
为我们自定义的类型去写运算符重载函数
也就是说 当我们写运算符重载函数的时候
它至少要有一个操作数 是我们自定义的类的对象
另一个操作数嘛 当然可以也是类的对象
或者呢 是基本类型的数据 都可以
那这个运算符重载函数可以重载为类的成员函数
也可以重载为类外的
非成员函数
到底怎么选择呢
有些运算符重载为成员函数或者非成员函数都可以
有些运算符呢
或者说 有些运算符
当它碰到左操作数不是对象的时候
你就只能把它重载为
非成员函数了
重载为非成员函数的时候呢
如果想提高运算效率
我们可以将这个重载函数定义为
类的友元
这样的话可以访问类的私有成员
它的运算效率就会比较高
那么这个函数
重载为非成员函数的时候 那么
左操作数就不要求必须是类的对象了
大家回去可以把这一章的例题
辅数运算那个例题呢 去扩展一下
再加几种不同的运算符重载函数的形式
比如说在类的成员函数中呢 你可以增加
辅数加实数 辅数减实数 让第二个操作数
是
基本类型的数据
不是复数
然后在重载为类外的非成员函数的时候呢
你可以让第一个操作数
是实数
实现实数加复数
实数减复数
大家可以回去试一试 然后这个自增自减运算符呢
我们看到了例题中呢 是在clock类里面实现了对象的自增一秒
包括它前置的++和后置的++
通过这个我们了解了后置++原来如此啊
终于大家明白了 是在加一之前就把原来那个数的副本存起来了
然后在运算中呢 用的是那个加一之前的那个副本
而
自己对象呢悄悄的加了一
实际上就这么一个意思
大家也可以 定义一些其他的类
试试你为它重载一下后置的单目运算符
在这一章呢 其实重点是学习它的动态多态性
动态多态性呢
我们简单的了解了一下它的原理
其实就是通过这个虚表来实现的
在每个具有虚函数的类里面呢
都有一个虚表
里面有指向各个虚函数函数体的
这个接口啊这个入口
而 具有虚函数的类 它的对象
除了我们显式定义的数据成员以外
都会有一个多出来的隐含的成员
就是指向虚表的指针
通过这个指向虚表的指针
在运行的时候呢
我们就可以通过这个指针找到它应该调用的那个函数的函数体
于是呢
我们就可以在类的定义的时候
在类体里面声明某些函数
它是虚函数 那就是告诉编译器
这个函数的调用表达式
你都不要在编译阶段去确定它对应哪个函数体
相反 你应该把这样的虚函数的函数体的入口放在这个类的虚表里面
那么 运行时 让他自己去识别 去找到这个函数体
所以呢 这就是我们实现多态性和动态绑定的这个虚函数
在基类中定义了虚函数以后
派生类继承过来
自动也就成为了虚函数
但是建议大家在派生类中
把这个virtual关键字也要写上
这样程序的可读性就会比较好
当我们定一个概念比较抽象的类的时候呢
其中有些函数可能由于信息不够具体算法无法实现
那么这个时候呢
可以把它定义为 纯虚函数
就是没有函数体
具有纯虚函数的类呢就叫做抽象类 那抽象类
它是不能定义实体的
不能实例化 不能定义对象的
它的作用就是
当别的类的基类
用来规范整个类家族的统一的对外接口和必须具有的功能
那么用这样的机制呢
我们就可以编写尽量通用的程序了
最后呢 我们还学习了c++11的
新的功能override和final
都是非常有用的
那这一章结束之后呢 希望大家多编程序 多实践