设为首页 加入收藏

TOP

C++虚函数机制分析
2014-11-12 17:00:09 来源: 作者: 【 】 浏览:24
Tags:函数 机制 分析

  虚函数是面向对象编程语言里一个很重要的机制,下面我们以一个c++例子,分析其对应的c语言程序来说明虚函数的机制。


  面向对象有了一个重要的概念就是对象的实例,对象的实例代表一个具体的对象,故其肯定有一个数据结构保存这实例的数据,这一数据包括变量,接口函数指针,如果是虚函数,则有相应的虚函数指针,其他函数指针不包括。


  要讲虚函数机制,必须讲继承,因为只有继承才有虚函数的动态绑定功能,先讲下c++继承对象实例内存分配基础知识:


  c++继承分为两种,普通继承和虚拟继承(virtual)。具体的继承又根据父类中的函数是否virtual而不同。


  下面就单继承分为几种情况阐述:


  1.普通继承+父类无virtual函数


  若子类没有新定义virtual函数 此时子类的布局是 : 由低地址->高地址 为父类的元素(没有vptr),子类的元素(没有vptr).


  若子类有新定义virtual函数 此时子类的布局是 : 由低地址->高地址 为父类的元素(没有vptr),子类的元素(包含vptr,指向vtable.)


  2. 普通继承+父类有virtual函数


  不管子类没有新定义virtual函数 此时子类的布局是 : 由低地址->高地址 为父类的元素(包含vptr), 子类的元素.


  如果子类有新定义的virtual函数,那么在父类的vptr(也就是第一个vptr)对应的vtable中添加一个函数指针.


  3.virtual继承


  若子类没有新定义virtual函数 此时子类的布局是 : 由低地址->高地址子类的元素(有vptr),虚基类的元素.为什么这里会出现vptr,因为虚基类派生出来的类中,虚类的对象不在固定位置(猜测应该是在内存的尾部),需要一个中介才能访问虚类的对象.所以虽然没有virtual函数,子类也需要有一个vptr,对应的vtable中需要有一项指向 虚基类.


  若子类有新定义virtual函数 此时子类的布局是与没有定义新virtual函数内存布局一致.但是在vtable中会多出新增的虚函数的指针.


  4.多重继承


  此时子类的布局是 : 由低地址->高地址 为父类p1的元素(p1按照实际情况确定元素中是否包含vptr), 父类p2的元素(p2按照实际情况确定元素中是否包含vptr),子类的元素.


  如果所有父类都没有vptr,那么如果子类定义了新的virtual function,那么子类的元素中会有vptr,对应的vtable会有相应的函数指针.


  如果有的父类存在vptr.如果子类定义了新的virtual function,会生成一个子类的vtable,这个子类的vtable是,在它的父类的vtable中后添加这个新的虚函数指针生成的.因为子类分配的空间显示并没有新增加一个4字节的指针空间,其实不管子类增加了多少新的虚函数,其空间大小不变,因为其和虚函数相关的分配的空间就是一个vptr,是一个指针,也就是4字节,不变,要变是变在vtable.


  比如如下一个类:


  Class test1() {};


  fun1() {};


  public Virtual a(){println(“test1:a”);};


  public Virtual b(int b){println(“test1:b”);};


  int a;


  }


  Class test2 extends test1{


  fun2(){};


  public Virtual b(int b){this->b++;println(“test2:b”) } ;


  public Vitrual c(){println(“test2:c}”)}


  int b;


  }


  Int main(){


  test1 a=new test2();


  a.b();


  }


】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇C++sizeof使用规则及陷阱分析(5) 下一篇指针数组和指向指针的指针

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容: