时间:2021-05-20
本文针对C++的虚函数的实现机制进行较为深入的分析,具体如下:
1、简单地说,虚函数是通过虚函数表实现的。那么,什么是虚函数表呢?
事实上,如果一个类中含有虚函数,则系统会为这个类分配一个指针成员指向一张虚函数表(vtbl),表中每一项指向一个虚函数的地址,实现上就是一个函数指针的数组。
例如下面这个例子:
下面列出了各个类的虚函数表(vtbl)的内容。
Parent类的vtbl:Parent::foo1( )的地址、Parent::foo1( )。
Child1类的vtbl:Child1::foo1( )的地址、Parent::foo1( )。
Child2类的vtbl:Child1::foo1( )的地址、Child2::foo1( )。
2、可以看出,虚函数表既有继承性,又有多态性。每个派生类的vtbl继承了它各个基类的vtbl,如果基类vtbl中包含某一项,则派生类的vtbl中也将包含同样的一项,但是两项的值可能不同。如果派生类覆盖了该项对应的虚函数,则派生类vtbl的该指针先指向重载后的虚函数,没有重载的话,则沿用基类的值。
3、在类对象的内存布局中,首先是该类的vtbl指针,然后才是对象数据。在通过对象指针调用一个虚函数时,编译器生成的代码将先获取对象类的vtbl指针,然后调用vtbl中对应的项。对于通过对象指针调用的情况,在编译期间无法确定指针指向的是基类对象还是派生类对象,或者是哪个派生类的对象。但是在运行期间执行到调用语句时,这一点已经确定,编译后的调用代码能够根据具体对象获取正确的vtbl,调用正确地虚函数,从而实现多态性。
4、分析一下这里的思想所在:
问题的实质是这样,对于发出虚函数调用的这个对象指针,在编译期间缺乏更多的信息,而在运行期间具备足够的信息,但那时已不再进行绑定了,怎么在二者之间做一个过渡呢?
把绑定所需的信息用一种通用的数据结构记录下来,该数据结构可以同对象指针相联系,在编译时只需要使用这个数据结构进行抽象的绑定,而在运行期间将会得到真正的绑定。这个数据结构就是vtbl。可以看到,实现用户所需的抽象和多态需要进行后绑定,而编译器又是通过抽象和多态实现后绑定的。
声明:本页内容来源网络,仅供用户参考;我单位不保证亦不表示资料全面及准确无误,也不保证亦不表示这些资料为最新信息,如因任何原因,本网内容或者用户因倚赖本网内容造成任何损失或损害,我单位将不会负任何法律责任。如涉及版权问题,请提交至online#300.cn邮箱联系删除。
为了实现虚函数,C++使用了虚函数表来达到延迟绑定的目的。虚函数表在动态/延迟绑定行为中用于查询调用的函数。尽管要描述清楚虚函数表的机制会多费点口舌,但其实其本
虚函数主要实现了C++的多态的机制,多态就是用父类型别的指针指向其子类的实例,然后通过父类的指针调用实际子类的成员函数。 C++是C语言的继承,它既可以进行C
前言c++分为编译时多态和运行时多态。运行时多态依赖于虚函数,大部分人或许听说过虚函数是由虚函数表+虚函数指针实现的,但,真的是这样吗?虽然c++规范有着复杂的
1.C++中的虚函数C++中的虚函数的作用主要是实现了多态的机制。关于多态,简而言之就是用父类型别的指针指向其子类的实例,然后通过父类的指针调用实际子类的成员函
1、C++对象的内存分布和虚函数表:C++对象的内存分布和虚函数表注意,对象中保存的是虚函数表指针,而不是虚函数表,虚函数表在编译阶段就已经生成,同类的不同对象