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 ...
随机推荐
- 2013 - Lost connection to MySQL server at 'reading initial communication packet' 错误解决
一.操作与状态 当使用MySQL客户端连接localhost本地数据库时,连接不上,报错.(使用Tomcat连接数据库时可以连接上,但需要很长的请求时间.) 二.原因与解决办法 关于这个问题网上的解决 ...
- Hyperion Business Modeling for Microsoft Windows (32-bit)
介质包搜索 常见问题 说明 复查 许可证列表 以确定需要下载的产品程序包. 请选择产品程序包和平台,然后单击“查找”. 如果只有一项结果,则可以看到下载页.如果有多个结果,请选择一个,然后单 ...
- ASP.NET后台执行JS代码
1. 用Response.Write方法 代码如下:Response.Write("<script type='text/javascript'>alert("XXX& ...
- 刚刚开通博客,分享Asp.Net的GridView的基本用法
包含有 数据的编辑,删除, 标题的添加,自定义分页,高亮显示鼠标所在,以及数据不足时添加空行 aspx页面代码 <asp:GridView ID="GridView1" ru ...
- 回文串--- Girls' research
HDU 3294 Problem Description One day, sailormoon girls are so delighted that they intend to resear ...
- [moka同学笔记]yii2.0 advanced高级版 安装配置 与 rbac (Ⅰ)
1.下载地址:http://www.yiichina.com/download,下载 Yii2 的高级应用程序模板 2.配置与安装 在服务器www目录下yii2test [下载下来更改advance ...
- IOS6学习笔记(二)
四.使用关联引用为分类添加数据 虽然不能在分类中创建实例变量,但是可以创建关联引用(associative reference).通过关联引用,你可以向任何对象中添加键-值(key-value)数据. ...
- swift学习笔记之-构造过程
//构造过程 import UIKit /* 构造过程(Initialization): 1.构造过程是使用类.结构体或枚举类型的一个实例的准备过程.在新实例可用前必须执行这个过程,具体操作包括设置实 ...
- Javascript对象赋值操作
首先,我们还是举个例子来说明对象赋值操作的问题吧: ps: 本文默认约定log = console.log function A(){} A.prototype.x = 10; var a1 = ne ...
- 关于ol有序裂变和ul无序列表前面的列表项标记的位置
使用列表项标记的时候发现其对齐方式竟然从内容开始,于是发现了这个属性可以解决: list-style-position inside 列表项目标记放置在文本以内,且环绕文本根据标记对齐. outsid ...