对使用虚函数表调用函数方法的解读
来源:互联网 发布:知乎营销模式 编辑:程序博客网 时间:2024/06/05 09:35
假设我们有这样的一个类:
class Base {
public:
virtual void f() { cout << "Base::f" << endl; }
virtual void g() { cout << "Base::g" << endl; }
virtual void h() { cout << "Base::h" << endl; }
};
按照上面的说法,我们可以通过Base的实例来得到虚函数表。 下面是实际例程:
typedef void(*Fun)(void);
Base b;
Fun pFun = NULL;
cout << "虚函数表地址:" << (int*)(&b) << endl;
cout << "虚函数表 — 第一个函数地址:" << (int*)*(int*)(&b) << endl;
// Invoke the first virtual function
pFun = (Fun)*((int*)*(int*)(&b));
pFun();
实际运行经果如下:(Windows XP+VS2003, Linux 2.6.22 + GCC 4.1.3)
虚函数表地址:0012FED4
虚函数表 — 第一个函数地址:0044F148
Base::f
通过这个示例,我们可以看到,我们可以通过强行把&b转成int *,取得虚函数表的地址,然后,再次取址就可以得到第一个虚函数的地址了,也就是Base::f(),这在上面的程序中得到了验证(把int* 强制转成了函数指针)。通过这个示例,我们就可以知道如果要调用Base::g()和Base::h(),其代码如下:
(Fun)*((int*)*(int*)(&b)+0); // Base::f()
(Fun)*((int*)*(int*)(&b)+1); // Base::g()
(Fun)*((int*)*(int*)(&b)+2); // Base::h()
内存地址,实际上就是这块内存的编号。
无论什么类型的指针,都是一样的。。当你强转成另一种类型时,系统也就认为,这个指针所指的内容的格式是这样的。。
也就是说,char* 的指针,系统就认为里面内容的格式是字符类型;你把它强转成 int * 那么系统就认为他的内容是 int 类型。。就这样。。而int** 也就是 二维数组 的格式。。
- 对使用虚函数表调用函数方法的解读
- 函数的调用方法
- MSSQL对函数的调用方法不止一种哦
- js 实现定时对函数的调用setInterval()方法
- 对类成员函数的另类调用方法
- 对函数的简单调用
- C++调用虚函数的方法
- 对结构体函数模式的使用和结构体数组函数的调用
- JavaScript调用函数的方法
- JavaScript调用函数的方法
- mybaits调用函数的方法
- js调用函数的方法
- 函数指针使用与直接函数调用对程序代码大小的影响
- 解读linux对string.h函数的实现
- 解读linux对string.h函数的实现
- 解读linux对string.h函数的实现
- 解读linux对string.h函数的实现
- 解读linux对string.h函数的实现
- 如何启动/停止Oracle数据库
- 经典sql查询小结
- AsyncTask 小结
- 对特定规则文字进行排序
- VS技巧
- 对使用虚函数表调用函数方法的解读
- lua Table的序列化与反序列化函数
- Rebuild Current BSP and Subprojects的陷阱
- 查看Oracle工作状态
- 转自**人
- 一个高效的hash str map 的实现
- php给$_POST,$_GET过滤单引号与双引号安全函数
- 对于骨架类(AbstractInterface)的理解
- 关于XML文件的异常:The processing instruction target matching "[xX][mM][lL]" is not allowed.