首页
社区
课程
招聘
[原创]C++的类_this指针_多态以及虚表_汇编分析后源码验证!!!
发表于: 2021-9-29 23:08 7597

[原创]C++的类_this指针_多态以及虚表_汇编分析后源码验证!!!

2021-9-29 23:08
7597

 

从图中可以看出,确实是读表访问来调用函数,

而且只有1张书中所说的虚表


 

从图中可以看出当三角继承的时候出现了2张虚表

普通函数调用默认会把类指针(this)由ecx传进去


接下来,我们用源码的方式去实现验证下这些

本来想一点一点讲的,累了,一次都写上去,

直接验证,下面再把源码放上吧

相信有图,有源码,大家很快就能自行验证理解了


我大概写下类内存结构

C类
{
A类指针---->书中把这个称为虚表指针?
A类变量A
B类指针---->书中把这个称为虚表指针?
B类变量B
C类变量C
C类变量A
}
C类的虚函数会被放在A类的虚表里


源码如下:

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
class A类
{
public:
    int A = 111;
    virtual void 函数()
    {
        std::cout << "A类函数:" << endl;
    }
    virtual void 函数_A()
    {
        std::cout << "A类函数_A:"<< endl;
    }
};
class B类
{
public:
    int B = 222;
    virtual void 函数()
    {
        std::cout << "B类函数"<< endl;
    }
    virtual void 函数_B()
    {
        std::cout << "B类函数_B"<< endl;
    }
};
class C类 : A类, B类
{
public:
    int C = 333;
    int A = 444;
    void 函数()
    {
        std::cout << "C类函数" << endl;
    }
    void 函数_A()
    {
        std::cout << "C类函数_A" << endl;
    }
    void 函数_B()
    {
        std::cout << "C类函数_B" << endl;
    }
    virtual void 函数_D()
    {
        std::cout << "C类函数_DDDDDD" << endl;
    }
    void 正经函数()
    {
        std::cout << "C类函数_正经靓仔..." << endl;
    }
};
 
//正常调用一次,虚表调用一次,打印2行一样的
void 调用A类(A类* A)
{
    auto 虚表 = (int*)((int*)A)[0];
    std::cout << "...进入A类调用..." << endl;
 
    A->函数();   
    ((void(*)(void)) * 虚表)();//函数
 
    A->函数_A();
    ((void(*)(void)) * (虚表 + 1))();//函数A
    std::cout << "...调用A类强转后输出_变量A:" << A->A << endl;
    std::cout << "...退出A类调用..." << endl;
    ((void(*)(void)) * (虚表 + 2))();//函数_D   _因为C类的虚函数放在第一张表里
}
 
//正常调用一次,虚表调用一次,打印2行一样的
void 调用B类(B类* B)
{
    auto 虚表 = (int*)((int*)B)[0];
    std::cout << "...进入B类调用..." << endl;
 
    B->函数();
    ((void(*)(void)) * 虚表)();//函数
 
    B->函数_B();
    std::cout << "...这里测试B类的B变量输出:" << B->B << endl;
    std::cout << "...退出B类调用..." << endl;
    std::cout << "-----------------" << endl;
    *(int*)B = *(int*)(new B类());//替换B类虚表
}
 
 
int main()
{
    C类* C = new C类();
    auto 类表 = (int*)C;
    std::cout << "...开始搞事情..." << endl;
    std::cout << "-----------------" << endl;
    std::cout << "...记录虚表值..." << endl;
    C->函数();
    C->函数_A();
    C->函数_B();
    std::cout << "-----------------" << endl;
 
    std::cout << "-----------------" << endl;
    调用A类((A类*)类表);
    std::cout << "-----------------" << endl;
    std::cout << "---A类里的A变量值:"<< *(类表 + 1) << endl;
    调用B类((B类*)(类表 + 2));
    std::cout << "-----------------" << endl;
    std::cout << "---B类里的B变量值:" << *(类表 + 3) << endl;
    std::cout << "---A类里的C变量值:" << *(类表 + 4) << endl;
    std::cout << "---A类里的A变量值:" << *(类表 + 5) << endl;
    std::cout << "-----------------" << endl;
 
    std::cout << "...更新虚表后..." << endl;
    C->函数();
    C->函数_A();
    C->函数_B();
    std::cout << "-----------------" << endl;
    std::cout << "...结束搞事情..." << endl;
    return NULL;
}


[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

收藏
免费 0
支持
分享
最新回复 (0)
游客
登录 | 注册 方可回帖
返回
//