阿龙的学习笔记---《深度探索C++对象模型》读书笔记(三)--- Data语意学

本文是《深度探索C++对象模型》的读书笔记,探讨了C++中数据成员的存储和访问,包括静态与非静态数据成员的区别,以及继承对数据成员的影响。重点讲解了虚继承如何解决菱形继承问题,分析了不同编译器对于虚基类的实现方式,如vbptr和vbtable,并提出了C++之父Bjarne的创新思路。
摘要由CSDN通过智能技术生成
  • 占用空间: 空的基类是1字节的大小,由于编译器需要使得不同的对象有不同的地址,以及其他因素,会给空的class一个char,分配空间。如果继承这个类,那么可能会占用这1字节的空间,但新的编译器可能会优化掉,比如在32位机器上,以下两种可能性:

  • 在这里插入图片描述
    在这里插入图片描述

  • 同名: 外部声明的同名变量,一般会被class内部的变量覆盖。

  • 内存中 顺序: non-static data members 在 class object 中的排列顺序将和其被声明的顺序一样。


data的存取:

  • static data member 的存取没有什么成本,static对象存放在进程空间数据段固定位置,无论是对象存取还是指针存取,都会转化为className::staticDataName这样的实现。
  • 欲对一个 non-static data member进行存取操作,编译器需要把 class object的起始地址加上 data member 的偏移位置。
  • 如果是虚继承基类中的data,那么会慢一些,因为会多一层指针操作 。

继承与data member:

  • 最简单的无多态的继承对象模型是这样:虽然中间有多个由于字节对齐而产生的空白部分,但是这是必须的,否则在赋值或者切割时,会有不必要的情况发生,比如obj1->obj2,那char bit2的位置就会传入一个随机数,这不是想要的结果。
    在这里插入图片描述

  • 加了多态的C++需要多处理些什么呢??

    • 首先,类中如果有virtual functioin, 那么则需要引入一个virtual table,里面存储着虚函数的指针。
    • 每个object中都会有一个vptr,用于指向那个table,从而实现动态链接。
    • 加强构造函数,让构造函数完成vptr的部分。以及在derived class 的构造函数中,重新设定vptr的值。
    • 加强析构函数,完成 vptr 的工作。
  • 有多态的单一继承模型:vptr的位置不一定在头部或是尾部,根据编译器而定。
    在这里插入图片描述

  • 无多态、无虚继承的多重继承:继承关系如下

    • 在这里插入图片描述

    • 而对象模型如下: 按照继承的顺序排列:在这里插入图片描述

    • 像上面那样,对像指针转换的时候可能会出问题:由于V3D和第二个继承的Vertex头部没有直接对齐
      在这里插入图片描述

  • 虚拟继承

    • 虚拟继承解决了菱形多重继承中有多个重复基类的问题。虚继承会将模型中分为不变区域和共享区域。
    • 不变区域中的数据,不管后继如何衍化,总是拥有固定的oet(从 object的开头算起),所以这一部分数据可以被直接存取。至于共享区域,所表现的就是 virtual base class subobject这一部分的数据,其位置会因为每次的派生操作而有变化,所以它们只可以被间接存取。各家编译器实现技术之间的差异就在于间接存取的方法。
    • 比如还是类似上面的例子,变成下面这个菱形继承的方式,采用虚基类virtual base class。
      在这里插入图片描述
    • 大部分编译器设计的方法:以指针指向virtual base class(可以参考这个博客https://www.cnblogs.com/zhjblogs/p/14274188.html
      参考下面这两个图解释一下,虚继承的类会以一个vbptr指针的方式存在,指针指出了这个v-base class的偏移。在D类(也就是Vertex3d)中,两个继承来的B和C都包含这样的一个指针,而共享区域的A,会被重新放在D的最下面(而不是重复放在B和C的下面)。这时,两个vbptr指向这个开始位置。这个偏移信息是由一个vbtable来报存。vbtable记录了从这个vptr到这个v-base class的位置偏移(即图中的D::vbtable@B@)。
      在这里插入图片描述
      在这里插入图片描述
    • 文中还有一个开脑洞的想法,觉得很奇妙!C++之父 Bjarne 喜欢的方法。在虚函数表的负索引的位置,存放v-base的偏移。这样解决了 在类中不需要对每一个v-base都添加一个指针的问题。
      在这里插入图片描述
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值