《深度探索C++对象模型》笔记——Data语意学

Data Member的绑定

  • inline member functin躯体之内的一个data member绑定操作会在整个class声明完成之后才发生。
  • argument list中的名称还是会在它们第一次遭遇时被适当地决议。
  • 为避免错误,早期出现三种防御性代码风格,把data members放在class声明开始处,把inline functions放在class声明之外,把nested type声明放在class的起始处。

Data Member的布局

  • static data members放在程序的data segment中,和class objects无关。
  • 同一个access section中的data members的排列符合较晚出现的data members在class object中有较高的地址。
  • 允许多个access section中的data members自由排列。
  • derived class members和base class(es) members可以自由排列。
  • 在大部分编译器上头,base class members总是先出现,但属于virtual base class的除外。
  • 编译器内部产生出来的data members可自由地放在任何位置上。

Data Member的存取

  • 通过对象、引用或指针存取一个static data member的成本是一样的,存取许可不会招致任何空间上或时间上的额外负担。
  • 通过对象、引用或指针存取一个nonstatic data member的成本,其效率和存取一个C struct member或一个nonderived class的member(单一继承或多重继承)是一样的(多重继承的时候,members的位置在编译时就固定了,存取members只是一个简单的offset运算)。
  • 通过引用或指针比通过对象存取一个virtual base class的member的速度会稍慢一点(我们不知道这个引用或指针指向哪一种class type,也就不知道编译期这个member真正的offset的位置,所以这个存取操作必须延迟至执行期,经由一个额外的间接导引,才能够解决)。

继承与Data Member

  • 单继承的时候,出现在derived class中的base class subobject有其完整的原样性。
  • 单继承加上多态的时候,vptr放在class object的前端,对于“在多重继承之下,通过指向class members的指针调用virtual function”,会带来一些帮助。当然这样就丧失了,vptr放在class object尾端对C语言的兼容性。
  • 多重继承的时候,对于一个多重派生对象,将其地址/指针指定给第二个或后继的base class的地址/指针,需要将地址/指针内部转化后再进行指定,有时内部转换操作还需要一个条件测试。
  • 虚拟继承的时候,为支持virtual base classes,在derived class中会添加一个指针,它或者指向virtual base class subobject(固定时间负担,不因virtual base classes的个数而有所变化),或者指向一个相关表格(固定时间负担,不因虚拟继承的尝试而改变),表格中存放的若不是virtual base classsubject的地址(Visual Studio)就是其偏移地址(CodeBlocks)。

指向Data Member的指针

  • 取一个static data member的地址得到的将是它在内存中的地址,类型是一个指向其数据类型的指针,而不是指向其class member的指针。
  • 取一个nonstatic datamember的地址,将会得到它在class中的offset,类型是一个指向其class member的指针。
  • 取一个绑定于真正class object身上的data member的地址,将会得到该member在内存中的真正地址,类型是一个指向其数据类型的指针。
原文地址:https://www.cnblogs.com/shuaihanhungry/p/5758363.html