C++中多态实现的内部原理

 多态,其实就是函数指针的灵活运行。
    首先你要知道什么叫继承,继承在内存中就是:class B : public A ==> class B inlucde class A,B的内存中的开始部分是A,当你多继承的时候,也就是第一个项,这就是为什么你强制类型转换后,还能继续访问基类的原因,什么都没有变,只不过使用了类型标志,限定了长度而已。
    函数(普通函数,非虚)都是存在在类型上的,可以这样去理解:就是函数在类型的命名空间里,因此你的程序被编译后永远都是安装顺序一步一步走的,所以任何时间都最多只能有一个实例来访问类型的方法,C++中,这个东西就被叫做this。
    但虚函数呢,其实也是存储在类型上的,但如果这样的话,多态就出8来了。虚函数将会被委派一个函数指针,也就是通常说的的vtable的指针,这个指针是作为一个数据成员出现的,虽然所有从一个类得到的实例都一样,但还是要有一个指针,毕竟嘛,指针只有四个字节长度那么大。
    这样vtable是作为类型的第一个被定义的,只有这样在类型被上塑的时候才不会丢失vtable信息,并且一个类只有一个vtable,这样的话,继承后的类的vtable一般都和父类的vtable不一样,当你调用虚方法的时候,其实就调用了真正内存结构的里的vtable所指的方法。
    所以:你的对象上溯的时候类型信息并没有丢失,你简直就可以这样理解,当你使用了虚方法,并且有不同的实现体时,类里面已经定义了一个标志变量,来帮你标志实际的类型。而实际上,C++的效果也正是这样的。

 

 

就像楼上说,在C++的编译过程中,类的存储就大体是一个结构体(几去掉成员函数),作为一个完整的封装类型,这其中,指针起到了举足轻重的作用。
   比如class b 
      {
        int a;
        virtual fun1();
        void    fun2();
      }
   在编译后的结构形式大体为
     vtable     4字节
     int a      4字节
vtable 的作用就是为多态准备的,它是编译后虚表指针所指向的一张表(虚函数的地址表),也就是说有表的项数就为虚函数的个数,每继承一种新的类,就要为其重写了的虚函数重写他的虚表,没有重写的就直接指向其父类的地址,从而达到多态的作用,这些都是在编译的时候由编译器自动完成的。
   也许你要问fun2的地址怎么不用存储了,是的,它直接就可以在编译的时候用其函数指针确定;
   编译器直接可以翻译成;CALL fun2的地址。

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值