C++对象在内存中的存储

来源:互联网 发布:小野妹子学吐槽 淘宝 编辑:程序博客网 时间:2024/06/01 10:25

最近忽然迷惑,子类继承父类之后,子类对象在内存中的存储方式是怎样的。理论上上应该是虚函数表指针、父类变量、子类变量。父类变量存储时是否和子类变量一起实现内存对齐呢?

为了搞明白这个问题,做了如下实验。

编译环境:win32,VS2008,Version3.5 SP1

#include "stdafx.h"
#include<iostream>

using namespace std;

class A
{
public:
A(char ch){m_a = ch;}
virtual void funcA(){cout<<"virtual funcA"<<endl;}
public:
char m_a;

};

class B:public A
{
public:
B(char ch):A('A')
{
m_b = ch;
m_b1 = ch;
}
virtual void  funcB(){cout<<"virtual funcB"<<endl;}
public:
char m_b;
char m_b1;
};


int _tmain(int argc, _TCHAR* argv[])
{
A a('A');
B b('B');
int aa = 0;
typedef void (*FUNCP)(void) ;
       FUNCP fpA = NULL, fpB = NULL;

int *p = NULL;
int *pp = NULL;
printf("sizeof(A) = %d\n",sizeof(a));// 8
printf("sizeof(B) = %d\n",sizeof(b));// 12


printf("address of a = %0x\n",(long)&a);   // 2dfb54
printf("address of a.m_a = %0x\n",(long)&a.m_a);// 2dfb58

printf("address of b = %0x\n",(long)&b);//2dfb40
printf("address of b.m_a = %0x\n",(long)&b.m_a);// 2dfb44
printf("address of b.m_b = %0x\n",(long)&b.m_b);// 2dfb48
printf("address of b.m_b1 = %0x\n",(long)&b.m_b1);// 2dfb49

p = (int *)(&b.m_a-4);
pp =(int *) *p;

fpA = (FUNCP)*pp;
fpA(); //virtual funcA

fpB = (FUNCP)*(pp+1);
fpB(); //virtual funcB

scanf("%d\n",&aa);
return 0;
}

从输出结果来看,子类对象的确是按照虚函数表指针,父类变量,子类变量的顺序存储。

而且父类变量不跟子类变量一起参与内存对齐。


从类对象起始地址向后移动虚函数指针所占内存大小之后,即可以访问到类对象的数据,

无论此数据的属性是公有还是私有或者保护型。这从一定意义上破坏了类的封装性,但是虽然能够访问到数据,

却不知道数据的类型。



0 0
原创粉丝点击