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 ...
随机推荐
- [CLR via C#]9. 参数
一.可选参数和命名参数 在设计一个方法的参数时,可为部分或全部参数分配默认值.然后,调用这些方法的代码时可以选择不指定部分实参,接受默认值.此外,调用方法时,还可以通过指定参数名称的方式为其传递实参. ...
- table.appand(行数据) datagrid分页
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.We ...
- Android入门:Activity四种启动模式
一.启动模式介绍 启动模式简单地说就是Activity启动时的策略,在AndroidManifest.xml中的标签的android:launchMode属性设置: 启动模式有4种,分别为standa ...
- ActiveReports 9 新功能:创新的报表分层设计理念
在最新发布的ActiveReports 9报表控件中添加了多项新功能,以帮助你在更短的时间里创建外观绚丽.功能强大的报表系统,本文将重点介绍创新的报表分层设计理念,对报表内容进行分组管理与设计,易于实 ...
- 无法打开Android SDK Manager的解决办法
不知道从什么时候开始,打开Android的SDK Manager.exe时,命令行窗口一闪就自动关掉了. 想更新一些Android的东西都更新不了. 查了一下,解决办法是: 环境变量的系统变量Path ...
- ztree addNode editName removeNode
1.ztree api中完全拥有以上操作的相关解释,及简单Demo. 2.主要是要学会将单独的效果组合起来使用. 2.1 如: 添加完新的Node节点之后,怎么立即进入新节点的编辑状态来修改名称(或 ...
- 那些教程没有的php3-命名空间
php.net (PHP 5 >= 5.3.0, PHP 7) 定义命名空间 虽然任意合法的PHP代码都可以包含在命名空间中,但只有以下类型的代码受命名空间的影响,它们是:类(包括抽象类和tra ...
- IT外包行业与职业发展
在IT行业,总是有一些IT外包公司的存在,凡是存在的都是合理的.当你做为IT从业人员应该尽量避免去外包公司工作 .特别是你从事软件开发工作. 先来说说缘由,一些外包公司本来是从事软 ...
- SharePoint固定的Footer
原文地址:http://www.eliostruyf.com/sticky-footer-solution-for-sharepoint-2013/ 照搬全文: OFFICE 365 & SH ...
- 与成都的幸福行动家交流GTD
今年第四次来成都了,通过<小强升职记>的作者邹鑫的撮合,与成都的幸福行动家何平取得了联系,2014年12月6日下午给几个小伙伴们分享了GTD3年来的一点体会.有几位刚接触GTD的朋友,也有 ...