我对以下代码中的指针语句感到困惑。 指针的目的是从虚拟表访问虚拟函数。这是文章的链接。 http://kaisar-haque.blogspot.com/2008/07/c-accessing-virtual-table.html
1 #include <iostream>
2
3 using namespace std;
4
5 //a simple class
6 class X
7 {
8 public:
9 //fn is a simple virtual function
10 virtual void fn()
11 {
12 cout << "n = " << n << endl;
13 }
14
15 //a member variable
16 int n;
17 };
18
19 int main()
20 {
21 //create an object (obj) of class X
22 X *obj = new X();
23 obj->n = 10;
24
25 //get the virtual table pointer of object obj
26 int* vptr = *(int**)obj;
27
28 // we shall call the function fn, but first the following assembly code
29 // is required to make obj as 'this' pointer as we shall call
30 // function fn() directly from the virtual table
31 __asm
32 {
33 mov ecx, obj
34 }
35
36 //function fn is the first entry of the virtual table, so it's vptr[0]
37 ( (void (*)()) vptr[0] )();
38
39 //the above is the same as the following
40 //obj->fn();
41
42 return 0;
43 }
44
所以,我想知道如何理解第26行。
答案 0 :(得分:1)
代码试图基于c ++中虚拟功能的某些可能实现进行黑客入侵。 vtable的实现未在标准中定义,并且不同的编译器可能会有所不同。也可能需要进行优化。
本文已有10年历史,并假设有一个特殊的vtable实现,在那之前是很常见的:
对象中的第一个隐藏指针(在对象起始地址处)指向函数数组。
函数数组表示该类中的所有虚函数。 只有编译器知道它们在数组中的放置顺序。通常使用声明顺序。
假设上述实现,“ obj”的地址实际上是指向虚拟表的指针的地址。该示例使用假设函数指针可以表示为int
。对于64位OS和许多其他操作系统,这根本不是事实。 int *vptr
是指向此数组的指针。因此, obj 指向一个指向int (int**)
数组的指针。因此,*(int**)obj
是指向数组本身的指针。
然后,该示例又进行了另一个不安全的转换,即从vptr [0](为'int')到指向该函数的指针。
因此,结果是,您遇到了一系列不确定的或不安全的行为,这些行为可能适用于特定编译器的特定版本的特定实现(可能与本文相同,已有10年历史了)。
请勿使用!!!