转自http://www.tuicool.com/articles/uiUJry

一个空的class在内存中多少字节?如果加入一个成员函数后是多大?这个成员函数存储在内存中什么部分?

一个Class对象需要占用多大的内存空间。最权威的结论是: 
    *非静态成员变量总合。 
    *加上编译器为了CPU计算,作出的数据对齐处理。 
    *加上为了支持虚函数,产生的额外负担。

介绍完了理论知识后,再看看再找一个例子看看(注:一下所有结果都是在VC6.0 开发环境中得出的结论) 
一、空类的Size

  1. class Car
  2. {
  3. };
  4.  
  5. void main()
  6. {
  7. int size = 0;
  8. Car objCar;
  9. size = sizeof(objCar);
  10. printf("%s %d /r", "Class Car Size:", size);
  11. }
  12.  
  13. 输出结果:Class Car Size:1

试想一个“不占空间“的变量如何被取地址、两个不同的“空类/结构”变量又如何得以区分呢,于是,“空类/结构体”变量也得被存储,这样编译器也就只能为其分配一个字节的空间用于占位了。 
编译器在执行Car objCar;这行代码后需要,作出一个Class Car的Object。并且这个Object的地址还是独一无二的,于是编译器就会给空类创建一个隐含的一个字节的空间。

二、只有成员变量的Size

  1. class Car
  2. {
  3. private:
  4. int nLength;
  5. int nWidth;
  6. };
  7.  
  8. void main()
  9. {
  10. int size = 0;
  11. Car objCar;
  12. size = sizeof(objCar);
  13. printf("%s %d /r", "Class Car Size:", size);
  14. }
  15.  
  16. 输出结果:Class Car Size:8

这个结果很多开发人员都清楚。在32位系统中,整型变量占4个字节。这里Class Car中含有两个整型类型的成员变量,所以Class Size是8。

  1. class Car
  2. {
  3. private:
  4. int nLength;
  5. int nWidth;
  6. static int sHigh;
  7. };
  8.  
  9. void main()
  10. {
  11. int size = 0;
  12. Car objCar;
  13. size = sizeof(objCar);
  14. printf("%s %d /r", "Class Car Size:", size);
  15. }
  16. 输出结果:Class Car Size:8

我们这次在Class Car中添加了一个静态成员变量,但是Class Size仍然是8个字节。这正好符合了,结论中的第一条:非静态成员变量总合。

  1. class Car
  2. {
  3. private:
  4. char chLogo
  5. int nLength;
  6. int nWidth;
  7. static int sHigh;
  8. };
  9.  
  10. void main()
  11. {
  12. int size = 0;
  13. Car objCar;
  14. size = sizeof(objCar);
  15. printf("%s %d /r", "Class Car Size:", size);
  16. }
  17. 输出结果:Class Car Size:12

在类中又插入了一个字符型变量,结果Class Size变成了12。这个就是编译器额外添加3个字符变量,做数据对齐处理,为了是提高CPU的计算速度。编译器额外添加的东西我们是无法看见的。这也符合了结论中的第二条:加上编译器为了CPU计算,作出的数据对齐处理。 
既然,我们这样定义类成员数据编译器会额外的增加空。那么,我们何不在定义类的时候就考虑到数据对齐的问题,可以多定义出3个字符类型变量作为预留变量,既能满足数据对齐的要求,也给自己的程序添加了一些可扩展的空间。

三、只有成员函数的Size

  1. class Car
  2. {
  3. public:
  4. Car(){};
  5. ~Car(){};
  6. public:
  7. void Fun(){};
  8. };
  9.  
  10. void main()
  11. {
  12. int size = 0;
  13. Car objCar;
  14. size = sizeof(objCar);
  15. printf("%s %d /r", "Class Car Size:", size);
  16. }
  17. 输出结果:Class Car Size:1

噢,这是怎么回事儿呢?再做一个实验看看。

  1. class Car
  2. {
  3. public:
  4. Car(){};
  5. ~Car(){};
  6. public:
  7. void Fun(){};
  8. private:
  9. int nLength;
  10. int nWidth;
  11. };
  12.  
  13. void main()
  14. {
  15. int size = 0;
  16. Car objCar;
  17. size = sizeof(objCar);
  18. printf("%s %d /r", "Class Car Size:", size);
  19. }
  20. 输出结果:Class Car Size:8

这次应该很清楚的了。函数是不占用类空间的。第一个例子中的Size为1个字节,正是编译器为类创建一个隐含的一个字节的空间

  1. class Car
  2. {
  3. public:
  4. Car(){};
  5. virtual ~Car(){};
  6. public:
  7. void Fun(){};
  8. };
  9.  
  10. void main()
  11. {
  12. int size = 0;
  13. Car objCar;
  14. size = sizeof(objCar);
  15. printf("%s %d /r", "Class Car Size:", size);
  16. }
  17. 输出结果:Class Car Size:4

这次,让析构函数为虚函数,看到了Class Size为4。这正是指向Virtual Table的指针vptr的Size。这正好符合了,结论中的第三条:加上为了支持虚函数,产生的额外负担。

C++类的大小计算的更多相关文章

  1. C++类的大小计算汇总

    C++中类涉及到虚函数成员.静态成员.虚继承.多继承.空类等. 类,作为一种类型定义,是没有大小可言的. 类的大小,指的是类的对象所占的大小.因此,用sizeof对一个类型名操作,得到的是具有该类型实 ...

  2. C++类所占内存大小计算

    C++类所占内存大小计算 说明:笔者的操作系统是32位的. class A {}; sizeof( A ) = ? sizeof( A ) = 1明明是空类,为什么编译器说它是1呢? 空类同样可以实例 ...

  3. C++类对象大小的计算

    (一)常规类大小计算 C++类对象计算需要考虑很多东西,如成员变量大小,内存对齐,是否有虚函数,是否有虚继承等.接下来,我将对此举例说明. 以下内存测试环境为Win7+VS2012,操作系统为32位 ...

  4. 关于虚拟继承类的大小问题探索,VC++ 和 G++ 结果是有区别的

    昨天笔试遇到个 关于类占用的空间大小的问题,以前没怎么重视,回来做个试验,还真发现了问题,以后各位笔试考官门,出题时请注明是用什么编译器. vc6/vc8 cl 和 Dev-C 的g++ 来做的测试: ...

  5. sizeof求类的大小

    用sizeof求类的大小,http://blog.csdn.net/szchtx/article/details/10254007(sizeof浅析(三)——求类的大小),这篇博文给出了非常详尽的举例 ...

  6. Java对象的内存布局以及对象所需内存大小计算详解

    1. 内存布局 在HotSpot虚拟机中,对象的内存布局可以分为三部分:对象头(Header). 实例数据(Instance Data)和对齐填充(Padding). 1) 对象头(Header): ...

  7. C++学习笔记(8)----C++类的大小

    C++类的大小 (i) 如下代码: #include<iostream> using namespace std; class CBase { }; class CDerive :publ ...

  8. Math类的数学计算功能

    //Math类的数学计算功能 public class MathTest { public static void main(String[] args) { /*----------下面是三角运算- ...

  9. 类的大小——sizeof 的研究

    类的大小——sizeof 的研究(1) 先看一个空的类占多少空间? class Base { public: Base(); ~Base(); }; 注意到我这里显示声明了构造跟析构,但是sizeof ...

随机推荐

  1. ubuntu linux修改文件所属用户(owner属主)和组(groud属组、用户组)

    使用chown命令可以修改文件或目录所属的用户: 命令格式:sudo chown 用户 目录或文件名 例如:sudo chown -R griduser /home/dir1  (把home目录下的d ...

  2. js之常见问题--for循环中为什么点击总是弹出最后一个i

    首先看看点击不同li标签时,弹出li的索引值对应的结果 HTML: <ul> <li>0</li> <li>2</li> <li> ...

  3. 将lits集合转化为树状结构

    一,bean的类型: public class DeptListRES { /** * 子节点 */ private List<DeptListRES> children; private ...

  4. mysql 用户及权限

    永远不要给任何人(除了MySQL root帐户)访问 数据库中的 user表mysql!这很关键. mysql.user表存放所有用户的主机,用户名,密码,权限.直接修改表中信息,需flush pri ...

  5. 我对于B-树索引的内部结构与索引类型所做的笔记

    图 3-1 B-树索引的内部结构 分支块和页块 B-树索引有两种类型的块: 用于查找的分支块和用于存储值的叶块.B-树索引的上层分支块包含指向下层索引块的索引数据.在图 3-1 中,根分支块包含条目 ...

  6. [iOS] 测试设备解决自签名证书问题

    不多说,解决过程都是泪. 用了最简单粗暴的方式. 1. 将你的自签名证书,放到测试设备可以访问的站点上 2. 用safari访问上面的地址,直接将证书安装到本设备上 搞掂! Have fun with ...

  7. IE 浏览器background image 属性问题

    background-size 如果以百分比的形式设置参数,第一个参数是宽度,第二页参数是高度.“如果只设置第一个参数,则第二个参数为auto”.这样设置,在Firefox chrome 浏览器中,图 ...

  8. (转载)关于管理计算机\\xp1 找不到网络路径的解决方案

    关于管理计算机\\xp1 找不到网络路径的解决方案 使用域管理员登录域控DC,然后打开AD用户和计算机 选择一台域成员计算机,然后选择管理,结果出现如下提示:点击确定后出现如下提示随后,立刻用域管理员 ...

  9. mysql 试题总结

    一.MySQL的复制原理以及流程 1.复制基本原理流程 1.主:binlog线程——记录下所有改变了数据库数据的语句,放进master上的binlog中: 2.从:io线程——在使用start sla ...

  10. python 回调函数,最简单的例子

    回调的英文定义: A callback is a function that is passed as an argument to another function and is executed ...