C++类所占内存大小计算
C++类所占内存大小计算
说明:笔者的操作系统是32位的。
class A {};
sizeof( A ) = ?
sizeof( A ) = 1
明明是空类,为什么编译器说它是1呢?
空类同样可以实例化,每个实例在内存中都有一个独一无二的地址,为了达到这个目的,编译器往往会给一个空类隐含的加一个字节,这样空类在实例化后在内存得到了独一无二的地址.所以sizeof( A )的大小为1.
class B
{
public:
B() {}
~B() {}
void MemberFuncTest( int para ) { }
static void StaticMemFuncTest( int para ){ }
};
sizeof( B ) = ?
sizeof( B ) = 1
类的非虚成员函数是不计算在内的,不管它是否静态。
class C
{
C(){}
virtual ~C() {}
};
sizeof( B ) = ?
sizeof( B ) = 4
类D有一个虚函数,存在虚函数的类都有一个一维的虚函数表叫虚表,虚表里存放的就是虚函数的地址了,因此,虚表是属于类的。这样的类对象的前四个字节是一个指向虚表的指针,类内部必须得保存这个虚表的起始指针。在32位的系统分配给虚表指针的大小为4个字节,所以最后得到类C的大小为4.
class D
{
D(){}
virtual ~D() {}
virtual int VirtualMemFuncTest1()=0;
virtual int VirtualMemFuncTest2()=0;
virtual int VirtualMemFuncTest3()=0;
};
sizeof( D ) = ?
sizeof( D ) = 4
原理同类C,不管类里面有多少个虚函数,类内部只要保存虚表的起始地址即可,虚函数地址都可以通过偏移等算法获得。
class E
{
int m_Int;
char m_Char;
};
sizeof( E ) = ?
sizeof( E ) = 8
32位的操作系统int占4个字节,char占一个字节,加上内存对齐的3字节,为8字节。
class F : public E
{
static int s_data ;
};
int F::s_data=100;
sizeof( F ) = ?
sizeof( F ) = 8
类F为什么跟类E一样大呢?类F的静态数据成员被编译器放在程序的一个global data members中,它是类的一个数据成员,但是它不影响类的大小,不管这个类实际产生了多少实例还是派生了多少新的类,静态成员数据在类中永远只有一个实体存在,而类的非静态数据成员只有被实例化的时候,他们才存在.但是类的静态数据成员一旦被声明,无论类是否被实例化,它都已存在.可以这么说,类的静态数据成员是一种特殊的全局变量.
class G : public E
{
virtual int VirtualMemFuncTest1(int para)=0;
int m_Int;
};
class H : public G
{
int m_Int;
};
sizeof( G ) = ?
sizeof( H ) = ?
sizeof( G ) = 16
sizeof( H ) = 20
可以看出子类的大小是本身成员的大小再加上父类成员的大小.如果父类还有父类,也加上父类的父类,这样一直递归下去。
class I : public D
{
virtual int VirtualMemFuncTest1()=0;
virtual int VirtualMemFuncTest2()=0;
};
sizeof( I ) = ?
sizeof( I ) = 4
父类子类工享一个虚函数指针,虚函数指针保留一个即可。
总结:
空的类也是会占用内存空间的,而且大小是1,原因是C++要求每个实例在内存中都有独一无二的地址。
(一)类内部的成员变量:
普通的变量:是要占用内存的,但是要注意内存对齐(这点和struct类型很相似)。
static修饰的静态变量:不占用内存,原因是编译器将其放在全局变量区。
从父类继承的变量:计算进子类中
(二)类内部的成员函数:
非虚函数(构造函数、静态函数、成员函数等):不占用内存。
虚函数:要占用4个字节(32位的操作系统),用来指定虚拟函数表的入口地址。跟虚函数的个数没有关系。父类子类工享一个虚函数指针。
构成对象本身的只有数据,任何成员函数都不隶属于任何一个对象,非静态成员函数与对象的关系就是绑定,绑定的中介就是this指针。成员函数为该类所有对象共享,不仅是处于简化语言实现、节省存储的目的,而且是为了使同类对象有一致的行为。同类对象的行为虽然一致,但是操作不同的数据成员。
测试代码如下:
- <span style="font-size: 18px;">/*
- * file name : main.cpp
- * description : test the size of c++'s class
- * create on : 2012-05-31
- * create by : chenchong
- * email : vision_chen@yeah.net
- */
- #include<iostream>
- using namespace std;
- class A {};
- class B
- {
- public:
- B() {}
- ~B() {}
- void MemberFuncTest( int para ) { }
- static void StaticMemFuncTest( int para ){ }
- };
- class C
- {
- C(){}
- virtual ~C() {}
- };
- class D
- {
- D(){}
- virtual ~D() {}
- virtual int VirtualMemFuncTest1()=0;
- virtual int VirtualMemFuncTest2()=0;
- virtual int VirtualMemFuncTest3()=0;
- };
- class E
- {
- int m_Int;
- char m_Char;
- };
- class F : public E
- {
- static int s_data ;
- };
- int F::s_data=100;
- class G : public E
- {
- virtual int VirtualMemFuncTest1(int para)=0;
- int m_Int;
- };
- class H : public G
- {
- int m_Int;
- };
- class I : public D
- {
- virtual int VirtualMemFuncTest1()=0;
- virtual int VirtualMemFuncTest2()=0;
- };
- int main( int argc, char **argv )
- {
- cout<<"sizeof( A ) = "<<sizeof( A )<<endl;
- cout<<"sizeof( B ) = "<<sizeof( B )<<endl;
- cout<<"sizeof( C ) = "<<sizeof( C )<<endl;
- cout<<"sizeof( D ) = "<<sizeof( D )<<endl;
- cout<<"sizeof( E ) = "<<sizeof( E )<<endl;
- cout<<"sizeof( F ) = "<<sizeof( F )<<endl;
- cout<<"sizeof( G ) = "<<sizeof( G )<<endl;
- cout<<"sizeof( H ) = "<<sizeof( H )<<endl;
- cout<<"sizeof( I ) = "<<sizeof( I )<<endl;
- #if defined( _WIN32 )
- system("pause");
- #endif
- return 0;
- }
- </span>
/*
* file name : main.cpp
* description : test the size of c++'s class
* create on : 2012-05-31
* create by : chenchong
* email : vision_chen@yeah.net
*/ #include<iostream> using namespace std; class A {}; class B
{
public:
B() {}
~B() {}
void MemberFuncTest( int para ) { }
static void StaticMemFuncTest( int para ){ }
}; class C
{
C(){}
virtual ~C() {}
}; class D
{
D(){}
virtual ~D() {}
virtual int VirtualMemFuncTest1()=0;
virtual int VirtualMemFuncTest2()=0;
virtual int VirtualMemFuncTest3()=0;
}; class E
{
int m_Int;
char m_Char;
}; class F : public E
{
static int s_data ;
};
int F::s_data=100; class G : public E
{
virtual int VirtualMemFuncTest1(int para)=0;
int m_Int;
};
class H : public G
{
int m_Int;
}; class I : public D
{
virtual int VirtualMemFuncTest1()=0;
virtual int VirtualMemFuncTest2()=0;
}; int main( int argc, char **argv )
{
cout<<"sizeof( A ) = "<<sizeof( A )<<endl;
cout<<"sizeof( B ) = "<<sizeof( B )<<endl;
cout<<"sizeof( C ) = "<<sizeof( C )<<endl;
cout<<"sizeof( D ) = "<<sizeof( D )<<endl;
cout<<"sizeof( E ) = "<<sizeof( E )<<endl;
cout<<"sizeof( F ) = "<<sizeof( F )<<endl;
cout<<"sizeof( G ) = "<<sizeof( G )<<endl;
cout<<"sizeof( H ) = "<<sizeof( H )<<endl;
cout<<"sizeof( I ) = "<<sizeof( I )<<endl; #if defined( _WIN32 )
system("pause");
#endif
return 0;
}
Windows 7 32位 VC 2010运行结果:

Linux(cent os 6.2 32位)运行结果:

C++类所占内存大小计算的更多相关文章
- C++中的类所占内存空间总结
C++中的类所占内存空间总结 最近在复习c++的一些基础,感觉这篇文章很不错,转载来,大家看看! 类所占内存的大小是由成员变量(静态变量除外)决定的,成员函数(这是笼统的说,后面会细说)是不计算 ...
- C++之类成员所占内存大小问题总结
1.空类所占字节数为1,可见代码如下 #include <iostream> using namespace std; class Parent { }; class Child:publ ...
- C++中的类所占内存空间总结(转)
类所占内存的大小是由成员变量(静态变量除外)决定的,成员函数(这是笼统的说,后面会细说)是不计算在内的. 摘抄部分: 成员函数还是以一般的函数一样的存在.a.fun()是通过fun(a.this)来调 ...
- 4种方法教你如何查看java对象所占内存大小
摘要:本文讲述4种查看java对象所占内存大小的方法 本文分享自华为云社区<查看java对象所占内存大小>,作者:xiewenci. 计算java对象所占内存大小 1.使用jdk8自带AP ...
- Java对象的内存布局以及对象所需内存大小计算详解
1. 内存布局 在HotSpot虚拟机中,对象的内存布局可以分为三部分:对象头(Header). 实例数据(Instance Data)和对齐填充(Padding). 1) 对象头(Header): ...
- YUV和RGB格式单像素所占内存大小分析
图片的大小定 义为:w * h,宽高分别为w和h 一.YUV格式 1.1.YUV420格式存储方式:先Y,后V,中间是U.其中的Y是w * h,U和V是w/2 * (h/2)举例:如果w = 4,h ...
- C++中的类所占内存空间+继承中的成员访问控制
C++学习之继承中的成员访问控制 C++中的类所占内存空间总结
- JAVA数组所占内存大小的对比
1.两个数据模型 第一个是基本类型数组,第二个使用的是Float对象数组 public class SummaryModel{ private float[] summaryData; public ...
- sizeof strlen strncpy用法总结 结构体实际所占内存大小 以及memset用法
sizeof测类型(数组名除外) strlen测实际长度 strncpy返回指针类型 #include <stdio.h> #include <stdlib.h> #inclu ...
随机推荐
- struts2 s:if标签以及 #,%{},%{#}的使用方法
<s:if>判断字符串的问题: 1.判断单个字符:<s:if test="#session.user.username=='c'"> 这样是从session ...
- 环信SDK与Apple Watch的结合(2)
这一篇主要是介绍怎么拖apple watch上的相关页面,附源码EMWatchOCDemo. 需要在工程中的“EMWatchOCDemo WatchKit App”中进行操作,该文件夹的结构如图 Wa ...
- wpf 下面用MVVC的RelayCommand命令引发的一个异常
具体解决方法参见我的博问:https://q.cnblogs.com/list/myquestion
- c# winForm 等待窗体的实现
最近在做一个项目,需要用到等待窗体,在DevExpress下面有SplashScreen控件可以使用,同时也有ProgressIndicator控件能用,但是如果没有用Dev开发的话,我们就需要自定义 ...
- Oracle基本操作汇总
--10g 新增的表空间类型:大文件 (Bigfile) 表空间.--10g 数据库在创建的时候,会指定默认的表空间类型.如果不特殊指定的话,默认为 SMALLFILE 类型的表空间.SELECT * ...
- 使用Dhcpstarv解决DHCP服务器冲突问题
场景: 内网环境需要开启多个DHCP服务器,分别给不同的设备进行PXE安装. 存在的问题: 多个DHCP的情况下,设备在启动时随机从一个DHCP服务器获取IP(哪个DHCP服务器先响应就从哪个获取)并 ...
- python之import机制
1. 标准 import Python 中所有加载到内存的模块都放在 sys.modules .当 import 一个模块时首先会在这个列表中查找是否已经加载了此模块,如果加载了则只是将 ...
- UGUI之Toggle使用
Toggle对象是一个开关.一般用于单选,可以用Toggle制作背包的选项卡 在场景中创建Toggle按钮.看看他有Toggle组件
- DP入门---饭卡
HDU 2546 Description 电子科大本部食堂的饭卡有一种很诡异的设计,即在购买之前判断余额.如果购买一个商品之前,卡上的剩余金额大于或等于5元,就一定可以购买成功(即使购买后卡上余额 ...
- 205 Isomorphic Strings
Given two strings s and t, determine if they are isomorphic. Two strings are isomorphic if the chara ...