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;
}
从输出结果来看,子类对象的确是按照虚函数表指针,父类变量,子类变量的顺序存储。
而且父类变量不跟子类变量一起参与内存对齐。
从类对象起始地址向后移动虚函数指针所占内存大小之后,即可以访问到类对象的数据,
无论此数据的属性是公有还是私有或者保护型。这从一定意义上破坏了类的封装性,但是虽然能够访问到数据,
却不知道数据的类型。
- 对象在内存中的存储
- 对象在内存中的存储
- C#和JAVA对象在内存中的存储
- 对象在内存中的存储机制
- Java 对象在内存中的存储
- C++对象在内存中的存储
- OC-对象在内存中的存储
- C/C++变量在内存中的存储
- C/C++ 变量在内存中的存储
- C语言数据在内存中的存储
- OC基础-06 对象在内存中的存储细节
- 父、子对象在内存中的存储01-16
- OC基础-类对象在内存中的存储方式13
- 负数在内存中的存储
- 数据在内存中的存储
- 数据在内存中的存储
- 数组在内存中的存储
- 字符串在内存中的存储
- JDBC部分回顾注意点
- 第九章(1)-事件处理机制-学习笔记
- sslsocket双向验证通信及单向验证通信
- Oracle中存储器(procedure)和触发器(trigger)的小例子
- android入门_采用HttpURLConnection的GET方式实现登陆案例
- C++对象在内存中的存储
- Linux下dpkg命令的使用
- 遍历逻辑卷
- 绿色安装MY_SQL
- 共勉
- App图标设计指南
- 如何优雅的使用 win10
- C# 3.0 新特性 学习(二):匿名类型、扩展方法
- zzulioj--1791-- 旋转矩阵(模拟水题)