C++内存分析(三)

document授权声明

    本文为Binhua Liu原创作品。本文允许复制,修改,传递。转载请注明出处。本文发表于2010年6月16日。

原文链接:http://www.cnblogs.com/Binhua-Liu/archive/2010/06/16/1759019.html 


document 前言

    在第二节我们讲到从带虚函数的基类继承的子类,有一个虚函数指针在对象的最前端。但是,如果基类没有虚函数而子类有呢?阅读本节请思考下面的问题:没有虚函数的基类,会有虚函数指针和虚函数表吗?从该类继承的子类,内存中的元素如何布局。

document Subject3:从不带虚函数的基类继承的子类

    我们把上一节的CBasic类的2个虚函数删除,CFinal从CBasic类继承并增加新的虚函数AVG。类图如下:
image
class  CBasic
{
   public :
       CBasic()
       {
           Array= new  int [2];
       }
       int  i;
       int  *Array;
      void  HelloWorld()
      {
          cout<< "hello world" <<endl;
      }
};   class  CFinal: public  CBasic
{
public :
      virtual   int  AVG( int  a, int  b)
       {
           return  a+b/2;
       }
     int  iFinal;
};
创建下面的对象
CBasic *b= new  CBasic;
CFinal *f = new  CFinal;
CBasic *b1=(CBasic *) f;

 

    我们还是可以用Watch窗口来观察对象中的元素的布局,但本章节不再详列分析过程。我们直接来看这种情况下对象的内存布局图:

 

image

    我们发现:观察CBasic类对象b,我们发现它没有虚函数指针;而CFinal类对象f有虚函数指针且位于对象地址的最前端;在CFinal类对象内存中,CBasic对象开始于紧接着虚函数指针后的地址;这意味着,当把CFinal类对象转换为CBasic类型时,对象指针指向的地址必须加上4个字节才能正确地指向CBasic对象。打印f和b1的值,我们发现,果然,b1=f+4。

document 结论

    本章节比较简短,让我们做出结论:

    对于从没有虚函数的基类继承的带虚函数的子类:

    1)其基类对象没有虚函数指针和虚函数表

    2)子类的虚函数指针位于对象内存的最前端,子类中的基类对象开始于紧接虚函数指针后的位置。

    3)子类对象转换为基类类型时,需要进行指针调整,对象指针指向的地址加4个字节,跳过虚函数指针的位置;反之,把基类对象转换为子类对象时,指针地址减4.

    4)子类对象的成员变量存储在紧接着基类对象结束后的位置。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值