这篇文章给大家介绍c++中多态的实现原理是什么,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。
1,说明
我们都知道多态指的是父类的指针在运行中指向子类,那么它的实现原理是什么呢?答案是虚函数表
在关于虚拟一文中,我们详细了解了c++多态的使用方式,我们知道没有虚拟关键子就没法使用多态
2,虚函数表
我们看一下下面的代码
class A { 公众: int 才能;我; virtual 才能;void  func (), {, cout & lt; & lt;,“A func", & lt; & lt;, endl;,} virtual 才能;void  func2 (), {, cout & lt; & lt;,“A func2", & lt; & lt;, endl;,} void 才能;func3 (), {, cout & lt; & lt;,“A func3", & lt; & lt;, endl;,} }; class B : public { int 才能;j; void 才能;func (), {, cout & lt; & lt;,“B func", & lt; & lt;, endl;,} void 才能;func3 (), {, cout & lt; & lt;,“B func3", & lt; & lt;, endl;,} }; int main () { cout 才能;& lt; & lt;, sizeof (A), & lt; & lt;,,,,,, & lt; & lt;, sizeof (B),,//输出,8、12 return 才能;0; }
在32位编译模式下,程序的运行结果是:8、12
但是如果把代码中的虚拟删掉,则程序的运行结果为:4,8
可以发现,有了虚函数之后,类所占的存储空间比没有虚函数多了4个字节,这个4个字节就是实现多态的关键,位于对象存储空间的最前端的指针,存放的是虚函数表的地址,这个是由编译器实现的
每个带有虚函数的类(包括其子类)都有虚函数表
虚函数表中存放着虚函数的地址,注意是虚函数的地址,非虚函数不在此列
虚函数表是编译器实现的,程序运行时被载入内存,一个类的虚函数表中列出了该类的全部虚函数地址。
例如,上面代码中,类一个的对象的存储空间以及虚函数表如图所示:
B类的对象的存储空间以及虚函数表,如下图所示:
多态的函数调用语句被编译成根据基类指针所指向的对象中存放的虚函数表的地址,在虚函数表中查找虚函数地址,并调用虚函数的一系列指令
3代码示例
在上面代码的基础上
A *, p =, new B (); p→func ();//B 函数 p→func3 ();//A func3 p→func2 ();//A func
第二行代码执行如下:
- <李>
取出p指针所指向的位置的前4个字节,即对象所属的类(类B)的虚函数表的地址(64位编译模式下是8个字节);
李> <李>根据虚函数表的地址找到虚函数的表,并在虚函数表中查找要调用的虚函数地址;
李> <李>调用虚函数;
李>到此,我们应该不难理解,上面第二行和第三行代码执行的分别是类的和类B的方法
执行 p→func (); 找的是B类虚函数表中func()地址,因为B类重写了,所以保存的是类B的函数()地址
而执行 p→func3 (); 的时候,发现func3()不是虚函数,所以并没有找虚函数列表,而是直接调用的p(类类型)的方法
同样的,执行 p→func2 (); 的时候,找的也是B类的虚函数表,因为B类没有重写func2,所以存的是类的一个的虚函数func2()的地址,所以执行了类一个的func2()方法
关于c++中多态的实现原理是什么就分享到这里了,希望以上内容可以对大家有一定的帮助,可以学到更多知识。如果觉得文章不错,可以把它分享出去让更多的人看的到。