本章用浅显的知识梳理一遍我对多态的理解 从头读到尾,心中形成多态知识体系树
1、多态分为静态多态和动态多态(通常我们所说的多态为动态多态,其实静态多态不太算多态)
2、首先来谈谈静态多态(编译时多态,在编译期间确定的)
静态多态可分为函数重载,运算符重载,类模板,泛型编程等等
其中函数重载为C语言和C++的区别(C语言是没有函数重载的,同时C++11特性也引入nullptr也是因为函数重载的原因)
(1)那么什么是函数重载?
函数重载是C++允许在同一作用域中声明几个类似的同名函数,
这些同名函数的形参列表(参数个数,类型,顺序)必须不同,
通过调用函数传参的不同,来实现对相同函数名函数的调用
(2)那么为什么运算符重载也能算重载?
各种数据进行“ + ”、“ - ”、“ * ”、“ / ”等运算操作其中不同的数据
类型对应不同的运算过程,这就体现了运算过程的多态性
(3)什么是类模板?
通过编译时,会根据对象定义的类模板类型,去匹配不同的类模板,
先匹配完全特化,再匹配部分特化,最后匹配普通特化
(4)什么是泛型编程?
泛型编程就是函数模板,和类模板有异曲同工之妙,对函数,
通过定义的数据类型个数或者类型进行函数匹配,不同与类模板,
优先考虑普通函数,如果有更好的匹配,那么选择函数模板
3、来谈谈动态多态(真正的多态)(在运行时确定的)
是面向对象的三大基本特征之一,而且是通过继承和虚函数实现的
虚函数实现了接口
具体讲讲两个例子
(1)每个带有虚函数的类中都有虚函数表,当对象实例化之后,
对象的内存地址首位有虚函数表指针,指向虚函数(每个对象实例化之后都有属于自己的虚函数表指针),
当虚函数调用时,会根据虚函数表指针去看虚表中的虚函数,
到底是访问哪一个虚函数(只有在运行时才能确定具体访问,故虚函数也不能做构造函数,就是这个原因)
函数重写,也是在这个地方,重写又叫隐藏,只有当父类为虚函数,
子类继承之后,不改变返回值,不改变参数(可加virtual可不加)
对父类函数进行实现,为重写,同时子类继承下来的父类虚函数会被覆盖(应该无法调用父类覆盖函数)
倘若改变了返回值或者参数,那么会被踢出虚函数表,同时被隐藏为普通函数,
为重定义(可通过域名符A::调用重定义函数)
(2)向下访问一般困难,但是虚函数恰恰实现了这个功能,
通过父类对象指针指向子类,可实现父类指针调用子类虚函数
(子类可以调用父类所有函数通过域名符,父类向下只能调用虚函数),
若非虚函数,则指针调用父类函数,
A *a = new B;
手动码字不易,原创文章,严禁转载
欢迎大家对我所述问题指正