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

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

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

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

class Car
{
}; void main()
{
int size = 0;
Car objCar;
size = sizeof(objCar);
printf("%s %d /r", "Class Car Size:", size);
} 输出结果:Class Car Size:1

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

二、只有成员变量的Size

class Car
{
private:
int nLength;
int nWidth;
}; void main()
{
int size = 0;
Car objCar;
size = sizeof(objCar);
printf("%s %d /r", "Class Car Size:", size);
} 输出结果:Class Car Size:8

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

class Car
{
private:
int nLength;
int nWidth;
static int sHigh;
}; void main()
{
int size = 0;
Car objCar;
size = sizeof(objCar);
printf("%s %d /r", "Class Car Size:", size);
}
输出结果:Class Car Size:8

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

class Car
{
private:
char chLogo
int nLength;
int nWidth;
static int sHigh;
}; void main()
{
int size = 0;
Car objCar;
size = sizeof(objCar);
printf("%s %d /r", "Class Car Size:", size);
}
输出结果:Class Car Size:12

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

三、只有成员函数的Size

class Car
{
public:
Car(){};
~Car(){};
public:
void Fun(){};
}; void main()
{
int size = 0;
Car objCar;
size = sizeof(objCar);
printf("%s %d /r", "Class Car Size:", size);
}
输出结果:Class Car Size:1

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

class Car
{
public:
Car(){};
~Car(){};
public:
void Fun(){};
private:
int nLength;
int nWidth;
}; void main()
{
int size = 0;
Car objCar;
size = sizeof(objCar);
printf("%s %d /r", "Class Car Size:", size);
}
输出结果:Class Car Size:8

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

class Car
{
public:
Car(){};
virtual ~Car(){};
public:
void Fun(){};
}; void main()
{
int size = 0;
Car objCar;
size = sizeof(objCar);
printf("%s %d /r", "Class Car Size:", size);
}
输出结果: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. 解决url传中文参数问题

    项目中要做一个表格导出功能,用的是location.url传值给后台导出表格数据.由于传中文会出现乱码现象.故需要给参数转码,具体如下: 对于url要传的中文参数进行两次编码(注意是两次),即enco ...

  2. dokuwiki 安装配置

    dokuwiki如果在用户注册的时候,发生"发送密码邮件时产生错误.请联系管理员!",那么需要配置sendmail. 在linux平台下,参考这个帖子https://www.dok ...

  3. Web开发——HTML基础(图像、音频和视频内容)

    参考: 参考:HTML中的图像 参考:视频和音频内容 目录: 1.HTML中的图像 1.1 我们如何在网页上放置图像? (1)替代文字(alt) (2)宽度和高度 (3)图片标题 1.2 用图形和图形 ...

  4. [redis] <<The little Redis book>>的读书笔记

    <<The Little Redis Book>> 请右键点击在新窗口打开,可按原始大小查看.

  5. spring和springboot

    Spring四大原则: 1.使用POJO进行轻量级和最小侵入式开发 2.通过依赖注入和基于接口编程实现松耦合 3,.通过AOP和默认习惯进行声明式编程 4.使用AOP和模版template减少模式化代 ...

  6. python框架之Django(1)-第一个Django项目

    准备 自己写一个简单的webServer import socket # 生成socket实例对象 sk = socket.socket() # 绑定IP和端口 sk.bind(("127. ...

  7. release 步骤

    一:在新的 TR 里面创建自己的task 1: /n se01 进入自己的用户名下面 2:display 3:选中自己的名字右键>check object 4:选中自己的名字右键> dir ...

  8. autoMapper的介绍

    .NET的DTO映射工具AutoMapper 分类: 多层架构 DTO .NET2012-08-11 10:27 2466人阅读 评论(0) 收藏 举报 原文:https://github.com/A ...

  9. ubuntu14安装mantis实践(包含LAMP/PHP)

    安装LAMP 参考 https://www.linuxidc.com/Linux/2016-12/138757.htm sudo add-apt-repository ppa:ondrej/apach ...

  10. 转换编码utf-8

    用这个enca -x utf-8 * 或者是 filename,还有别的方法,参见:https://blog.csdn.net/a280606790/article/details/8504133 我 ...