派生类地址比基类地址少4

大家对虚表并不陌生,都知道每个含有虚函数的类对象都有1个虚指针,但是在现实使用中,却总是因为这而调试半天,才发现原来是虚指针惹的祸。我这几天在调试代码时候也中招了,我的问题是这样的,如下图,CTree是最底层基类(非虚类), CSamplerTree(虚类)派生自CTree,CMSamplerTree,CASamplerTree派生自CSamplerTree,  

                                                        

CTree中包括两个成员变量,QList <CTree *> childList;树中有多少个孩子节点;CTree *parent;当前树节点的父亲节点,程序中我大量使用CTree *pTree指针指向CSamplerTree、CMSamplerTree、CASamplerTree ,从而达到统一处理的目的,从而使代码很简洁,复用性高。但是谁曾想到,程序一运行就会崩溃,通过调试发现,CSamplerTree、CMSamplerTree、CASamplerTree的指针当指向CTree的指针时,地址均加了4,为什么呢?为了加深理解,我做了一个简单的测试代码:

#include <stdio.h>class CBase {
public:
    CBase() {}
    void func()
    {
        printf("base\n");
    }
};
class CDerived : public CBase {
public:
	CDerived() {}
	virtual void func1()
	{
		printf("derived\n");
	}
};
void main()
{
     CBase *pBase = new CDerived();
     pBase->func();
     CDerived *pDerived = (CDerived *)pBase;
     printf("%d %d\n", pDerived, pBase);
     pDerived->func();	
     CBase *pBase1 = new CBase();
     pBase1->func();
     CDerived *pDerived1 = (CDerived *)pBase1;
     printf("%d %d\n", pDerived1, pBase1);
     pDerived1->func();
}

下面是输出的结果,从结果可以看出派生类指针指向基类指针,指针地址会加4,基类指针指向派生类时,指针地址会减4。

base
200672 200676
derived
base
200740 200744
Press any key to continue

下面我们看看派生类对象和基类对象的内存是如何组织的,我们在上例的基础上引入2个变量,代码如下:

#include <stdio.h>class CBase {
public:
    CBase() {}
    void func()
    {
        printf("base\n");
    }
    int a;
};
class CDerived : public CBase {
public:
	CDerived() {}
	virtual void func1()
	{
		printf("derived\n");
	}
       int b;
};
void main()
{
     CBase *pBase = new CDerived();
     CDerived *pDerived = (CDerived *)pBase;     
     printf("%d %d\n", pDerived, pBase);
     printf("%d %d %d\n", &pDerived->a, &pDerived->b, &pBase->a);
}

200672 200676
200676 200680 200676
Press any key to continue
从输出结果我们可看出,CDerived对象的起始地址存放的是虚表指针vptr,接下来的是基类的成员变量,接下来再是自身的成员变量。

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

RabinSong

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值