虚函数表的指针的内存布局

dd ecx
03B35EA8  6CC5849C  dChkData.6CC5849C
03B35EAC  003A0043
03B35EB0  0050005C

03B35EB4  006F0072

这儿先来看看虚函数表的指针的内存布局,具体看下例

#include <stdio.h>

class simpleClass{

public:

  static int nCount;

  int nValue;

  char c;

 

  simpleClass(){};

  virtual ~simpleClass(){};

 

  int getValue(void);

  virtual void foo(void){};

  static void addCount();

};

 

int main()

{

  simpleClass aSimple;

  printf("Object start address:   %x\n",&aSimple);

  printf("nValue address:         %x\n",&aSimple.nValue );

  printf("c address:              %x\n",&aSimple.c );

  printf("size: %d\n",sizeof(simpleClass));

  return 0;

}

所得结果如图所示:

 C++ 虚函数内存布局学习笔记 - coolwater2008 - Program for GameGIS

如是乎一个简单的C++对象的内存布局展示出来了:

C++ 虚函数内存布局学习笔记 - coolwater2008 - Program for GameGIS

由以上分析可以证明以下结论:

虚函数表的指针存在于对象实例中最前面的位置(我使用的是VC6,至于其他的编译器嘛,个人能力有限,有待以后考查)

【除此之外还包含有对其他许多知识点的验证:

1 非静态数据成员是影响对象占据内存大小的主要因素,随着对象数目的增加,非静态数据成员占据的内存会相应增加。

所有的对象共享一份静态数据成员,所以静态数据成员占据的内存的数量不会随着对象数目的增加而增长。

3 静态数据成员和非静态数据成员不会影响对象内存的大小,虽然其实现会占据相应的内存空间,同样也不会随着对象数目的增加而增加。】

还有一点需要补充的是:所有的虚函数共享同一张虚函数表。

对于子类实例中的虚函数表,是下面这个样子:

C++ 虚函数内存布局学习笔记 - coolwater2008 - Program for GameGIS

我们可以看到:

1  每个父类都有自己的虚表。

2  子类的成员函数被放到了第一个父类的表中。(所谓的第一个父类是按照声明顺序来判断的)

假设我们有这样的一个类:

class Base {

   public:

     virtualvoid f() { cout << "Base::f" << endl; }

     virtualvoid g() { cout << "Base::g" << endl; }

     virtualvoid h() { cout << "Base::h" << endl; }

 

};

对于实例:Derive d; 的虚函数表如下:

C++ 虚函数内存布局学习笔记 - coolwater2008 - Program for GameGIS

我们可以看到下面几点:

1)虚函数按照其声明顺序放于表中。

2)父类的虚函数在子类的虚函数前面。

因为在实际的应用中没有人会如此无聊的去定义这样的派生类Derive,所以读者可以自己尝试的写写验证程序,类似第一节中的pFun





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值