鱼C论坛

 找回密码
 立即注册
查看: 1845|回复: 0

[技术交流] C++中一个class类对象占用多少内字节

[复制链接]
发表于 2019-3-16 15:03:39 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
本帖最后由 RIXO 于 2019-3-16 15:06 编辑

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

一个Class对象需要占用多大的内存空间。最权威的结论是:

*非静态成员变量总合。
*加上编译器为了CPU计算,作出的数据对齐处理。
*加上为了支持虚函数,产生的额外负担。

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

  4. void main()
  5. {
  6.        int size = 0;
  7.        Car objCar;
  8.        size = sizeof(objCar);
  9.        printf("%s %d /r", "Class Car Size:", size);
  10. }
复制代码


输出结果:Class Car Size:1
这是为何呢?我想对于这个问题,不仅是刚入行不久的开发新手,就算有过几年以上C++开发经验的开发人员也未必能说清楚这个。
编译器在执行Car objCar;这行代码后需要,作出一个Class Car的Object。并且这个Object的地址还是独一无二的,于是编译器就会给空类创建一个隐含的一个字节的空间。

二、只有成员变量的Size

  1. class Car
  2. {
  3. private:
  4.        int nLength;
  5.        int nWidth;
  6. };

  7. void main()
  8. {
  9.        int size = 0;
  10.        Car objCar;
  11.        size = sizeof(objCar);
  12.        printf("%s %d /r", "Class Car Size:", size);
  13. }
复制代码

输出结果: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. void main()
  9. {
  10.        int size = 0;
  11.        Car objCar;
  12.        size = sizeof(objCar);
  13.        printf("%s %d /r", "Class Car Size:", size);
  14. }
复制代码

输出结果: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. void main()
  10. {
  11.        int size = 0;
  12.        Car objCar;
  13.        size = sizeof(objCar);
  14.        printf("%s %d /r", "Class Car Size:", size);
  15. }
复制代码

输出结果: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. void main()
  10. {
  11.        int size = 0;
  12.        Car objCar;
  13.        size = sizeof(objCar);
  14.        printf("%s %d /r", "Class Car Size:", size);
  15. }
复制代码

输出结果: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. void main()
  13. {
  14.        int size = 0;
  15.        Car objCar;
  16.        size = sizeof(objCar);
  17.        printf("%s %d /r", "Class Car Size:", size);
  18. }
复制代码

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

  1. class Car
  2. {
  3. public:
  4.        Car(){};
  5.        virtual ~Car(){};
  6. public:
  7.        void Fun(){};
  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. }
复制代码

输出结果:Class Car Size:4
这次,让析构函数为虚函数,看到了Class Size为4。这正是指向Virtual Table的指针vptr的Size。这正好符合了,结论中的第三条:加上为了支持虚函数,产生的额外负担。
转自:http://blog.ac521.org/?p=717
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2025-7-1 08:52

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表