类对象模型

举报
芒果_Mango 发表于 2022/07/31 23:13:51 2022/07/31
【摘要】 大家好,我是芒果,一名非科班的在校大学生。对C/C++、数据结构、Linux及MySql、算法等领域感兴趣,喜欢将所学知识写成博客记录下来。 希望该文章对你有所帮助!如果有错误请大佬们指正!共同学习交流作者简介:CSDN C/C++领域新星创作者https://blog.csdn.net/chuxinchangcun?type=blog掘金LV3用户 https://juejin.cn/us...

大家好,我是芒果,一名非科班的在校大学生。对C/C++、数据结构、Linux及MySql、算法等领域感兴趣,喜欢将所学知识写成博客记录下来。 希望该文章对你有所帮助!如果有错误请大佬们指正!共同学习交流

作者简介:


7.类对象模型

7.1 如何计算类对象的大小

类对象的存储方式猜测

  • 对象中包含类的各个成员

    image-20220116165607326

缺陷:每个对象中成员变量是不同的,但是调用同一份函数,如果按照此种方式存储,当一个类创建多 个对象时,每个对象中都会保存一份代码,相同代码保存多次,浪费空间。那么如何解决呢?


  • 只保存成员变量,成员函数存放在公共的代码段

image-20220116170045305

对象中存了成员变量,但是没有存成员函数!

每个对象都有独立的成员变量

不同对象调用成员函数,调用的是同一个!

class Stack
{
public:
    void Init() {};
    void Push(int x) {};
    //
//为了访问,把成员变量设为公有的
//private:
    int* _a;
    int _top;
    int _capacity;
};
int main()
{
    Stack s1;
    Stack s2;
    //每个对象中都有独立的成员变量
    s1._top = 0;
    s2._top = -1;
    //不同对象调用成员函数,调用的是同一个
    s1.Init();
    s2.Init();
    return 0;
}

image-20220116193318486

由汇编可以得知,二者调用的是同一个函数!


结论:计算类或者类对象大小的时候:只看成员变量,还要考虑内存对齐,C++的内存对齐规则和c结构体内存对齐规则一致

例子:

image-20220116194517258


// 类中既有成员变量,又有成员函数
class A1 {
    public:
    void f1(){}
    private:
    int _a;
};
// 类中仅有成员函数
class A2 {
    public:
    void f2() {}
};
// 类中什么都没有---空类
class A3
{};

sizeof(A1) : ****4__ sizeof(A2) : 1 sizeof(A3) : 1

结论:一个类的大小,实际就是该类中”成员变量”之和,当然也要进行内存对齐,注意空类的大小,空类比

较特殊,编译器给了空类一个字节来唯一标识这个类。

image-20220116193843428

空类会给1个字节的空间,这1个字节不存储有效数据,只是为了占位,表示对象存在!


sizeof()的意义是:算出这个实例化出的对象是多大,并不是说这个类多大。这个类被编译之后,并不存在内存当中,存在代码块当中
​
类实例化创建出的对象,数据并不是存在类中,而是存在对象中

7.3 结构体内存对齐规则

  1. 第一个成员在与结构体偏移量为0的地址处。
  2. 其他成员变量要对齐到某个数字(对齐数)的整数倍的地址处。

注意:对齐数 = 编译器默认的一个对齐数 与 该成员大小的较小值。 VS中默认的对齐数为8

  1. 结构体总大小为:最大对齐数(所有变量类型最大者与默认对齐参数取最小)的整数倍。
  2. 如果嵌套了结构体的情况,嵌套的结构体对齐到自己的最大对齐数的整数倍处,结构体的整体大小就是 所有最大对齐数(含嵌套结构体的对齐数)的整数倍。

【版权声明】本文为华为云社区用户原创内容,未经允许不得转载,如需转载请自行联系原作者进行授权。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。