在类外访问类的虚函数

前几天看了July哥的博客http://blog.csdn.net/v_JULY_v/archive/2011/05/26/6446364.aspx#1685620,讲的非常好,其中有一个问题不知是因为解释的不清楚,还是因为我的水平有限,一直没想明白。 

 

Fun pFun = (Fun)*((int*)*(int*)(&d)+0);各种指针转换、取地址,让哥凌乱了。今晚上理了一下,写在下面:

首先是随便搞的测试代码:

 

 

 

主要看一下比较有代表性的pFun_3(),为了清楚起见,我们引用了July博客中的图片:

 

多重继承示意图

 

虚表示意图

 

1、对于一个对象来说(例如代码中的c),其首地址所存储的是“指向第一个虚表的指针”,该指针也就是第一个虚表的首地址。

2、我们通过*操作符来取其元素(取“指向第一个虚表的指针”)。有人想直接这样:*(&c),这可不行!&c是Child型变量的地址,可取不到“指向第一个虚表的指针”;这时候得进行指针转换。

3、指针转换的类型要看你要取元素类型的大小。我们知道,指针的存储空间为4字节,所以我们要把&c首先转换成指向4字节类型的指针,再使用*操作符取其元素。这恐怕也就是*(int*)(&c)的来历了。既然这个指针转换的类型只与元素大小有关,我们也可以*(unsigned *)(&c)或者*(f*)(&c)甚至*(char ********)(&c),只要指针指向的是一个4字节类型就可以。

4、好了,我们取到了第一个虚表的首地址,但是同样的问题又出现了,虽然虚表的首地址得到了,但是要想取出虚表中的元素,还得根据元素类型的大小进行指针转换,我们知道,元素又是指针!那好吧,还是用(int *)转,谁让int型占4字节呢!然后就有了*(int *)*(int*)(&c)。这时候就得到了虚表中的元素--(虚)函数指针,再进行一个函数指针的转化就可以调用了。

5、至于那些+1和+2之类的东西,也是(int *)的转换的原因,否则如果(&c)+1,那可就直接加了个sizeof(class Child),取的不是“指向第二个虚表的指针”的地址,而是跑到对象存储空间的结尾去了。

 

从问题表面分析了一下,至于更加深入的问题还需要进一步的学习啊!

以上总结纯属个人思路,没有经过权威认证,还望各位高手多多指教!

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值