-
-
[原创]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; } |
赞赏
他的文章
看原图
赞赏
雪币:
留言: