• C++(四十)— C++中一个class类对象占用多少内字节


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

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

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

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

     1、空类的Size

      编译器在执行Car objCar;这行代码后需要,作出一个Class Car的Object。并且这个Object的地址还是独一无二的,于是编译器就会给空类创建一个隐含的一个字节的空间。

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

     2、只有成员变量的Size

     (1)在32位系统中,整型变量占4个字节。这里Class Car中含有两个整型类型的成员变量,所以Class Size是8。

    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

    (2)这次在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

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

    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

     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

      这次应该很清楚的了。函数是不占用类空间的。第一个例子中的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

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

    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
  • 相关阅读:
    jq封装的tab切换
    jquery高级函数
    jquery一些基本函数
    javascript中的事件冒泡和事件捕获
    prototype数组方法的实现
    瀑布流布局
    flex弹性布局
    js鼠标点击版tab切换
    js拖拽效果
    js根据className获取元素封装
  • 原文地址:https://www.cnblogs.com/eilearn/p/10958680.html
Copyright © 2020-2023  润新知