C++虚函数表的应用详解
程序员文章站
2022-06-22 19:33:24
我们知道在C++中要调用类的私有方法,我们可以使用友员(friend)的方式。但其实如果我们知道类的定义,完全可以根据该类对象的内存布局来直接调用它的私有函数。
本文作为&ldq...
我们知道在C++中要调用类的私有方法,我们可以使用友员(friend)的方式。但其实如果我们知道类的定义,完全可以根据该类对象的内存布局来直接调用它的私有函数。
本文作为“C++虚函数实现原理”的后续文章,并不打算介绍类的内存布局,本文只介绍如何使用虚函数表的方式来调用该类的私有虚函数。
现有如下Test类,提供了一个私有虚函数virtual void Func():
class Test { public: Test() { } virtual~ Test() { } private: virtual void Func() { printf("Private Function\n"); } };
现在我们使用虚函数表来调用Func成员函数:
typedef void(*PFN_Func)(); int main() { Test t; unsigned long **VirtualTable = (unsigned long **)(&t); unsigned long FuncAddr = VirtualTable[0][1]; PFN_Func pfnFunc = (PFN_Func)FuncAddr; if (pfnFunc) { pfnFunc(); } return 0; }
我们知道虚函数表其实就是一个二维数组。因为示例中的Test类没有继承于其他类,所以第一维只有一个元素;又因Test类有2个虚函数,故第二维有2个元素,且Func排在第二个,所以用VirtualTable[0][1]来取Func函数地址。
因为该示例运行在MSVC编译器环境,所以默认认为虚函数表位于类对象内存布局的起始位置,故直接使用了unsigned long **VirtualTable = (unsigned long **)(&t);。
严谨的做法应该是先判断虚函数表是否位于内存布局起始位置。
上一篇: C语言实现贪吃蛇(3):结构+链表实现