Chapter 3 Data语义学 The Semantics of Data
Data Member的绑定:主要是作用域的规定
Data Member的布局
类的static data member会放在程序的数据段(data segment)。
不同的access section的数据们放置没有强制的前后关系。vptr的放置也没有强制规定。
Data Member的存取
static data member的存取:
由于static data member放在程序的数据段,访问时用唯一的地址即可。
如果两个不同的class有同名的static data member,则这两个同名的member会被name-mangling(编码),基本就是加tag。
nonstatic data member的存取:
必须通过对象才能访问nonstatic data member(要不然访问的是谁的data member呢)。方法为对象的地址加上data member的offset就是这个data member的地址。
但在有虚拟继承的情况下,由于“经由base class subject存取class member”导入一层新的间接性,访问的时候,会有不同。考虑如下代码:
Point3d origin, *pt;
origin.x = 0;
pt->x;
由于origin一定是Point3d类型,所以origin.x编译时即可确定其offset。
但pt不一定是Point3d类型(多态),pt->x的存取需要延迟到执行期才能解决。
继承与Data Member
只继承不多态的情况
等价于base class的data member累加到本class中。
tips:累加时base class中的padding也随之而来了。
加上多态
需要处理vtbl和vptr。每个object中都有一个vptr。vptr的放置没有强制规定。
多重继承
虚拟继承
虚拟继承主要涉及到一个share的subobject。
如图所示的虚拟继承的情况,share Point2d subobject。
布局如图:
试想,如果Point2d也是像Vertex3d的一个类,则存在nested virtual base class指针。有编译器会把所有nested virtual base class指针全部拷贝到object中,以得到“固定存取时间”。
对象成员的效率Object Member Efficiency
指向Data Member的指针 Pointer to Data Member
& Point3d::z;的值为z在class object中的偏移量。
由于需要区分0偏移量和空指针,所以所有的偏移量都加上1,以避免出现0偏移量。
& p3d.z返回的则是对象p3d的z在内存中的偏移。