C++多态问题
首先就是多态的概念多态有静态多态和动态多态
静态多态:函数重载 和 运算符重载属于静态多态,复用函数名
动态多态:派生类 和 虚函数实现运行时多态
静态多态的函数地址早绑定,在编译阶段确定函数地址
动态多态的函数地址晚绑定,在运行阶段确定函数地址
动态多态的满足条件!!
1、有继承关系
2、父类有虚函数
3、子类要重写父类的虚函数
测试
首先我们先测试几个代码
1、父类对象的成员函数不是虚函数时
此时调用的就是父类的成员函数,这是就是静态多态,在编译阶段就已确定了函数地址,所以输出的时父类的成员函数。 ps:具体原因在后面
2、当父类的成员函数是虚函数时
这是用父类指针指向子类对象,调用的就是子类的成员函数,动态多态,在运行阶段确定函数地址
原理
大家先看这个代码,这个应该不难理解,因为成员函数分开存储,所以Base类相当于一个空类,而空类的大小是1字节
再看这段代码,与第一张图唯一的区别就是父类的成员函数加了关键字virtual,这时,这个成员函数就做虚函数。应该注意到的是此时的父类的大小变为4字节,这是因为此时父类产生了一个虚函数表指针vfptr(virtual function pointer),指向了虚函数表vftable(virtual function table),表中的内容就是test()这个成员函数的地址即&Base::test。我们可以通过vs自带的开发人员命令提示工具来证实
当父类发生继承时,父类中的所有成员都将被继承,包括这个虚函数表指针和虚函数表(这里其实也就可以说明为什么父类指针可以调用子类对象)。
这里看一下此时子类的内部结构
可以看到子类继承了父类的所有成员,然后我们重写父类的成员函数
此时再看子类的内部结构
可以看到原本在父类中的虚函数表中的父类的成员函数被覆盖,此时虚函数表中的内容是子类的成员函数地址&Son::test。相信大家应该会明白多态的原理了吧
这就是多态的体现,通过不同的对象调用不同的接口