Chinaunix首页 | 论坛 | 博客
  • 博客访问: 25812
  • 博文数量: 14
  • 博客积分: 2000
  • 博客等级: 大尉
  • 技术积分: 115
  • 用 户 组: 普通用户
  • 注册时间: 2009-05-24 13:36
文章分类

全部博文(14)

文章存档

2011年(1)

2009年(13)

我的朋友

分类: C/C++

2009-05-24 14:00:19

编译器是如何针对虚函数
产生可以再运行时刻确定被调用函数的代码呢?也就是说,虚函数实际上是如何被编译器处理的呢?Lippman在深度探索C++对象模型[1]中的不同章节讲到了几种方式,这里把“标准的”方式简单介绍一下。

     我所说的“标准”方式,也就是所谓的“VTABLE”机制。编译器发现一个类中有被声明为virtual的函数,就会为其搞一个虚函数表,也就是 VTABLE。VTABLE实际上是一个函数指针的数组,每个虚函数占用这个数组的一个slot。一个类只有一个VTABLE,不管它有多少个实例。派生 类有自己的VTABLE,但是派生类的VTABLE与基类的VTABLE有相同的函数排列顺序,同名的虚函数被放在两个数组的相同位置上。在创建类实例的 时候,编译器还会在每个实例的内存布局中增加一个vptr字段,该字段指向本类的VTABLE。通过这些手段,编译器在看到一个虚函数调用的时候,就会将 这个调用改写,针对1.1中的例子:

void bar(A * a)
{
     a->foo();
}

会被改写为:

void bar(A * a)
{
     (a->vptr[1])();
}

     因为派生类和基类的foo()函数具有相同的VTABLE索引,而他们的vptr又指向不同的VTABLE,因此通过这样的方法可以在运行时刻决定调用哪个foo()函数。
阅读(643) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~