c++ 虚表(上)

我们知道,c++ 中的多态,绝大多数的编译器都是通过虚表来实现的。

那么,我们是不是应该去探究下,编译器是怎样去管理的呢?

那么,好的,我们就通过代码来满足我们的好奇心吧。

首先,我们一步一步的来探究吧:

先来点简单的吧:(这里我默认大家对指针的使用很熟练的吐舌头

注意咯:我这里并没有为类添加成员,这是一个不足的地方,大家可以再看完之后,自己添加上去。

因为我这里主要是讨论虚表的问题,所以就偷了个懒。

好了,进入正题咯


一、单继承下的类图:(存在虚函数的覆盖)

Derived的内存是怎样分布的呢?虚函数是怎样存放在虚表中的呢?


 -          

我先把得出的结果以图形的方式描述出来,两个图放在一起更好的比较咯。


来看下我的代码吧:

      

是不是被这代码吓到了。不急我慢慢的来解析下:

类图的实现就不用我多说了吧。这个都看不懂的话,请移步。

void (*Func)()://定义一个函数指针,这个函数指针的返回值是void,参数是void.(我为什么这么做呢?因为我类中定义的函数就是这种类型的,后面有大用处呢。)

上面的理解了,那下面的这个不就很简单咯。

typedef void (*Func)();//将Func 作为一种数据类型,这个数据类型是返回值为void,参数是void 的函数指针

Base* b = new Derived;

Func fn = NULL;//声明一个变量咯,这个变量的类型是返回值为void,参数是void 的函数指针

fn = (Func)(*((int*)(*(int*)b)+0));//这个看的是不是很晕,好吧我这个复杂,就得用图形来解释咯。


还有,你是不是很奇怪,我为什么能够知道那么写?

首先,通过书本我知道,存在虚函数的对象,编译器都会去维护虚表。那我就想啊,这虚表时怎样存放虚函数的,还有指向续表的指针在对象的内存的那个位置。

然后就是不断的尝试咯。发现了其中的本质。当我tmp不断的往下指是,存放的函数一个一个的被调用出来了,到最后悔出现一个段错误,说明,后面的内存我不能在使用了。

所以就得出了如上的图形描述。


根据以上的代码,我们运行出的结果:



这样我们不就得出了Derived的虚表时怎样存放虚函数的了。

写完了,咱就得去总结下吧:

①在单继承存在虚函数的覆盖时,子类的对象只有一张虚表,子类对象的第一个索引指向的是虚表,虚表中存放虚函数的顺序是,先存放父类的虚函数,如果存在着子类覆盖

父类的虚函数,则父类的这个虚函数被覆盖。还有一点是,续表中存放的是栈中函数的地址。


看完第一个,咱是不是应该有点问题呢?难道只有一张虚表?多重继承下虚表又是怎样的呢?多重虚继承又是怎样的呢?多重继承抽象类呢?多重虚继承抽象类呢?

晕,好麻烦啊。咱就先把上面的看懂了。下一节再来吧。有什么不足之处欢迎大家的批评指出。

有什么问题或错误可以留言或Email:chenshan0821@sina.com

祝大家生活愉快。。。。。





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值