• C++对象模型学习


    更新记录

    时间 更新记录
    2020年4月6日 初稿

    背景

    • 自从转入iOS,学习到iOS的方法调度,runTime的知识,了解了一下iOS的对象模型。
    • 为了对iOS有更深入的了解,也对之前所学习的C++做一些补充,特此先学习一下C++的对象模型(说来也惭愧,windows开发一年半,没有看到C++对象模型相关的书或者网文)

    三种对象模型

    简单对象模型

    • 所有的成员变量、成员函数都作为对象在内存中的一部分
    • 简单、粗暴
    • 缺点:占用内存大,以生成对象个数线性递增。
      • 函数是所有对象共用,其实没有必要每个对象都记录,可以统一到某个地方。

    表格驱动模型

    • 区分数据成员和函数成员
    • 对象只存放数据表指针和函数表指针,所以对象内存固定
      • 针对于简单对象模型,表格驱动模型把数据成员列表作为每个对象独有的内存数据,而成员函数表则作为所有对象共享的内存数据,即可以解决简单对象模型“占用内存多”的问题
    • 缺点
      • 无法支持多态(确切地说,支持起来就比较复杂或者麻烦)
      • 查找数据成员时,较第一种方案多了一次寻址。而且每个对象都多了一个表格指针,内存升高了。
        • (要知道C++可是非常重视性能的,每次查找数据成员都要多一次寻址,而数据成员可能用的很多)
      • 调用成员函数时,较第一种方案多了一次寻址。
        • 同上,C++的成员函数也可能调用的很频繁

    当前的C++对象模型

    • 对象第一个字节(32位系统下)存储虚函数表指针(如继承树上有虚函数)
      • 虚函数一律放入虚函数表中,通过表格进行查找
      • 虚函数表的第一个slot存放type_info,用以支持RTTI
    • 后续依次存放父类到子类的(非静态)数据成员变量
    • 成员函数和全局函数类似,存放在代码区,不存储在对象相关内存中。
    • 优点
      • 查找数据,直接根据基地址+偏移量进行查找即可
      • 支持多态较简单
      • 成员函数调用快,直接根据符号寻址即可调用。相比表格驱动模型,不必多寻址一次。

    方法调度

    • 虚函数调用
      • 这也是面试中的高频考点
      • 通过实际的对象指针(即this指针),查找虚表,调用虚表中对应的函数。
      • 编译时所作工作
        • 将父类的虚函数和子类的虚函数进行逻辑判断,确定子类的虚函数表中存放的虚函数,是父类的虚函数实现,还是子类的虚函数实现
      • 运行时所作工作
        • 子类对象实际调用虚函数时,在运行时查找虚函数表,才知道调用的是哪个函数(是父类的,还是子类的)
    • 普通成员函数调用
      • 和全局函数调用类似
      • 注意:成员函数名必定不会冲突。
        • 因为普通成员函数的第一个参数是this指针,即使不同的类,普通成员函数名相同,函数参数也不同。

    参考资料

  • 相关阅读:
    Android屏幕适配全攻略(最权威的官方适配指导)--转
    Android实现全屏的三种方式
    Mysql锁(翻译)
    mysql5.6主从配置
    jvm加载类(更新中)
    如何定位jdk中的native方法源码?
    光学字符识别OCR-2
    光学字符识别OCR
    关于freetype在安装中的遇到的问题
    锚点链接
  • 原文地址:https://www.cnblogs.com/HelloGreen/p/12641645.html
Copyright © 2020-2023  润新知