Posts Tagged ‘函数指针’

14
Dec

虚函数表与函数指针数组

by huubby in C and CPP

从收藏夹里翻出个放了很久的帖子,内容是关于类对象中的虚函数指针和虚函数表的。想看具体内容请猛击这里

根据帖子内容和自己的认识,总结以下几点:

1、虚函数表指针位于类对象内存模型中的最前端,也就是说,一个类对象在内存中的地址范围内,前4个字节存放的是虚函数表的首地址,可以通过这个首地址访问到虚函数表。在上面的帖子里的第一个示例中,虚函数表的首地址就是:(int*)(*(int *) &b);

2、虚函数表中存放的是类对象的虚成员函数的首地址。虚函数表中的每一项又是一个指针,指向的是该虚成员函数的首地址,所以,可以通过虚函数表调用虚成员函数。还是上面帖子里的第一个例子,调用第一个虚成员函数的语句:

pFun = (Fun)*((int*)*(int*)(&b));
pFun();

其中,(int*)*(int*)(&b)就是虚函数表的第一项的地址。反引用之后,*((int*)*(int*)(&b))得到的就是第一个虚成员函数的首地址。将其强制转换后赋给函数指针pFun,此时,pFun指向的就是第一个虚成员函数的首地址,所以pFun()能够调用到Base::f。

3、在无虚函数覆盖的继承关系中,“虚函数按照其声明顺序放于表中”,并且“父类的虚函数在子类的虚函数前面”。

4、在有虚函数覆盖的继承关系中,子类中的函数覆盖掉父类的虚函数,覆盖的虚函数放到了虚函数表中父类被覆盖虚函数的位置,而“没有被覆盖的函数依旧”。这样的虚函数表结构,在实际调用过程中形成了多态。

5、对于多重继承,在子类的内存模型中,“每个父类都有自己的虚表”,“子类的成员函数被放到了第一个父类的表中”,其中“所谓的第一个父类是按照声明顺序来判断的”。

6、存在覆盖的多重继承中,子类的覆盖函数将取代其覆盖掉的父类的虚函数在虚函数表中的位置。

其实想起来去看虚函数表相关内容是因为在《高质量程序设计指南-C++/C》上看到一句话:在C++动态决议的虚拟机制中使用的vtable就是一个用来保存虚成员函数的地址的函数指针数组。看完虚函数表相关内容之后,稍微调整帖子里第一个例子的代码:
Read the rest of this entry »