C++多态本质-虚表

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
#include<windows.h>
#include<stdio.h>


class Test
{
public:

int a = 1;
int b = 2;

void func1()
{
return;
}
virtual void func2()
{
return;
}
};

class Base
{
public:
int a = 1;
int b = 2;
virtual void Func1()
{
puts("Func1");
}
virtual void Func2()
{
puts("Func2");
}
virtual void Func3()
{
puts("Func3");
}

private:

};

class Sub:Base
{
public:
virtual void Func5()
{
puts("Func4");
}virtual void Func4()
{
puts("Func5");
}virtual void Func6()
{
puts("Func6");
}
};

class SubSub:Sub
{
public:
virtual void Func7()
{
puts("Func7");
}virtual void Func8()
{
puts("Func8");
}virtual void Func9()
{
puts("Func9");
}
};

class Override:Base
{
public:
virtual void Func4()
{
puts("Func4");
}
virtual void Func5()
{
puts("Func5");
}
virtual void Func6()
{
puts("Func6");
}
virtual void Func2()
{
puts("Func2 Override");
}virtual void Func1()
{
puts("Func1 Override");
}
};

class Override2:Override
{
public:
virtual void Func7()
{
puts("Func7");
}virtual void Func8()
{
puts("Func8");
}virtual void Func9()
{
puts("Func9");
}

virtual void Func1()
{
puts("Func1 Override2");
}
virtual void Func4()
{
puts("Func4 Override2");
}
};

void test1() //通过对象调用时,虚函数和普通成员函数都是直接CALL(E8 ...)
{
Test t;
t.func1();
t.func2();
}

void test2() //通过类指针调用时,虚函数变为间接CALL(FF ...)
{
Test t;
Test* pt = &t;
pt->func1();
pt->func2();
}

void test3()
{
typedef void(*Proc)(void);
Sub s;
Sub* ps = &s;
ps->Func4();

for (size_t i = 0; i < 6; i++)
{
Proc vtFunc = (Proc)(*(int*)(*(int*)(&s) + 0x4 * i)); //对象的地址的前4字节为虚表的地址,虚表里保存虚函数的地址
printf("0x%x\t", (int)vtFunc); //单继承无重写,虚表按顺序来,父类到子类虚函数依次排列
vtFunc();
}

}

void test4()
{
typedef void(*Proc)(void);
Override s;
Override* ps = &s;

ps->Func1();

for (size_t i = 0; i < 4; i++)
{
Proc vtFunc = (Proc)(*(int*)(*(int*)(&s) + 0x4 * i));
printf("0x%x\t", (int)vtFunc); //单继承有重写,虚表中的函数地址会被重写的函数替换掉
vtFunc();
}
}

void test5()
{
typedef void(*Proc)(void);
SubSub s;
SubSub* ps = &s;

ps->Func7();

for (size_t i = 0; i < 9; i++)
{
Proc vtFunc = (Proc)(*(int*)(*(int*)(&s) + 0x4 * i));
printf("0x%x\t", (int)vtFunc); //多层继承无重写,虚表按顺序来,父类到子类再到子子类虚函数依次排列
vtFunc();
}

}

void test6()
{
typedef void(*Proc)(void);
Override2 s;
Override2* ps = &s;

ps->Func4();

for (size_t i = 0; i < 9; i++)
{
Proc vtFunc = (Proc)(*(int*)(*(int*)(&s) + 0x4 * i));
printf("0x%08x\t", (int)vtFunc); //多层继承有重写,
vtFunc();
}

}

void CheckVt()
{
Base b1;
Base b2;
Sub s;
Base* pb1 = &b1;
Base* pb2 = &b2;
Sub* ps = &s;
printf("0x%08x\n0x%08x\n", *(int*)pb1, *(int*)pb2);

}

int main()
{
//test6();
CheckVt();
return 0;
}

C++多态本质-虚表
https://rogxo.github.io/2021/12/01/2021-12-01-C++多态本质-虚表/
作者
Rogxo
发布于
2021年12月1日
许可协议
CC BY-NC-SA 4.0