[转帖]你指针学的如何?指针有什么过人之处?看看C++虚函数表中的指针_Android, Python及开发编程讨论区_Weblogic技术|Tuxedo技术|中间件技术|Oracle论坛|JAVA论坛|Linux/Unix技术|hadoop论坛_联动北方技术论坛  
网站首页 | 关于我们 | 服务中心 | 经验交流 | 公司荣誉 | 成功案例 | 合作伙伴 | 联系我们 |
联动北方-国内领先的云技术服务提供商
»  游客             当前位置:  论坛首页 »  自由讨论区 »  Android, Python及开发编程讨论区 »
总帖数
1
每页帖数
101/1页1
返回列表
0
发起投票  发起投票 发新帖子
查看: 3280 | 回复: 0   主题: [转帖]你指针学的如何?指针有什么过人之处?看看C++虚函数表中的指针        上一篇   下一篇 
huang.wang
注册用户
等级:中将
经验:17623
发帖:407
精华:1
注册:1970-1-1
状态:离线
发送短消息息给huang.wang 加好友    发送短消息息给huang.wang 发消息
发表于: IP:您无权察看 2018-8-9 9:25:11 | [全部帖] [楼主帖] 楼主


本文转自头条号C语言基础


前言

image.png

虚函数表: C++中的虚函数的作用主要是实现了多态的机制。关于多态,简而言之就是用父类型别的指针指向其子类的实例,然后通过父类的指针调用实际子类的成员函数。

对C++ 了解的人都应该知道虚函数(Virtual Function)是通过一张虚函数表(Virtual Table)来实现的。简称为V-Table。在这个表中,主是要一个类的虚函数的地址表,这张表解决了继承、覆盖的问题,保证其内容真实反应实际的函数。这样,在有虚函数的类的实例中这个表被分配在了这个实例的内存中。 C++的编译器应该是保证虚函数表的指针存在于对象实例中最前面的位置。这意味着我们通过对象实例的地址得到这张虚函数表,然后就可以遍历其中函数指针,并调用相应的函数。


无继承的虚函数表

有类如下:

image.png

对象--->虚函数表地址

image.png


输出

image.png

对*(int*)*(int*)(&b)的理解(看到后刺激不?)

image.png

如上图所示:实际就是一个指向指针的指针,需要两次解引用才能得到存储在虚函数表中的函虚数指针。

image.png


整个解析流程

b:Base类对象;

&b:Base类对象的首地址,因为 C++的编译器应该保证虚函数表的指针存在于对象实例中最前面的位置,也就是该地址存储的内容应该是虚函数表的地址;

(int *)(&b):对其进行强制类型转换成(int *)的目的是当对其执行间接访问操作时,可以访问到以该地址开始的连续四个字节的内存空间,因为指针总是要占四个字节的。

*(int *)(&b):第一次解引用,指向虚函数表,其值为虚函数表首字节的内容(虚函数表里存储的都是虚函数指针);

(int *)*(int *)(&b):对其进行强制类型转换成(int *)的目的是当对其执行间接访问操作时,可以访问到以该地址开始的连续四个字节的内存空间,因为指针总是要占四个字节的。强制类型转换之后该值表示虚函数指针表中第一个函数指针的地址,

*(int *)*(int *)(&b):第二次解引用。得到虚函数指针表中第一个函数指针,可以调用虚函数。


一般继承(无虚函数覆盖)

有类如下:

image.png

对象--->虚函数表地址

image.png

按上文所述,派生类对象d的虚函数表如下:

image.png

代码中for循环的条件为"i<3"时,可以输出派生类d重载的三个虚函数,说明派生类的f(), g(), h()函数将继承自Base类的这个三个函数覆盖。

注意:但将for循环的条件改为”i<6”时,执行时仍会报读内存错误。(具体原因大家可以自行套论一下)。


结束语

image.png

剩下三种情况自行分析,其实指针也就那么回事哦.(流泪。。。)

一般继承(有虚函数覆盖)

多重继承(无虚函数覆盖)

多重继承(有虚函数覆盖)



我超级酷,但是如果你回复我的话我可以不酷那么一小会儿。


——来自logo.png


赞(0)    操作        顶端 
总帖数
1
每页帖数
101/1页1
返回列表
发新帖子
请输入验证码: 点击刷新验证码
您需要登录后才可以回帖 登录 | 注册
技术讨论