目录:
1.多态的概念
2.多态的定义和实现
3.虚函数构成重写的特例
4.剖析一道非常经典的题
5.剖析多态的原理
-------------------------------------------------------------------------------------------------------------------------
1.多态的概念
概念:通俗来说,就是多种形态,具体点 就是去完成某个行为,当不同对象去完成时会产生不同的状态
2.多态的定义
关键字virtual -- 虚函数
构成虚函数的重写(覆盖) :(虚函数)+ 三同 (函数名、参数、返回值)
不符合重写,就是隐藏关系
虚函数构成重写只是构成多态的其中一种条件
第二个条件父类指针或者引用去调用函数
这里要是不构成多态,那么p.BuyTicket(),调用的就全是父类当中的那个BuyTicket(),这里st对象、sd对象传参给Func都发生了切片
但是这里构成了多态,也发生了切片,但是呢构成了多态,跟p的类型就没有关系,而是看它传过来指向的对象了
---------------------------------------------------------------------------------------------------------------
如果我们把不是用父类的指针或者引用去调用函数呢???
那如果我们的虚函数不构成重写呢
3.虚函数构成重写的特例
去掉子类的virtual虚函数
为什么呢 ???
把子类的virtual去掉,还是认为它是虚函数,原因是因为
参数不同
返回值也还有一个特例
重写的协变。返回值可以不同,要求必须是父子关系的指针或者引用
但是返回的可以是其它父子关系的指针或引用
父返回的必须是父类指针,子返回的必须是子类指针
4.剖析一道非常经典的题
A.A->0 B.B->1 C.A->1 D. B->0 E.编译错误 D.以上都不正确
func调用的肯定是子类的,最主要的这里的val是谁的
这里的val是父类的
虚函数重写是接口继承(把函数的函数名,参数、返回值继承下来)重写实现
普通函数继承是实现继承()
5.剖析多态的原理
为什么多态能实现指向谁就调用谁呢????
我们先看一个小问题 --- Base是有多大呢
这样子看的话,我们一般会认为是8字节 ,为什么呢 内存对齐嘛。整形的大小是4字节,然后char的大小是1字节,加起来5字节,不过呢内存对齐嘛,以4字节内存对齐,Base的大小得是4的整数倍。
可一看却是12字节,和我们算的不一样
可是这里考察的不是内存对齐,考察的是多态
Base类型的对象里,会多存一个指针,指针指向的是虚表(虚表指针)
我再增加几个虚函数,我们来看看它会不会进入我们的虚表呢???
那么我们的多态的原理(是如何做到指向谁就调用谁的),我们先简单讲讲
首先虚函数会存进虚表,对象里没有虚函数,有的只是虚表的指针
可是构成多态又是如何实现指向谁就调用谁的呢???
总结 :多态的本质原理,符合多态的两个条件
那么调用时,会到指定对象的虚表中找到对应的虚函数地址,进行调用
多态调用是程序运行时去指向对象的虚表中找到函数的地址,进行调用
普通函数的调用,编译或链接时,确定函数的地址,运行时直接调用