a、virtual base和virtual function带来的vptr影响2、Nonstatic data members在class object中的排列顺序将和其被声明顺序一样,任何中间介入的static data members都不会被放进布局之中。
b、 EBO (Empty Base class Optimize)空基类优化处理,EBC(Empty Base Class)占用一个字节,其他含有数据成员的从EBC派生的派生类,只会算自己数据成员的大小,不受EBC一字节的影响
c、alignment 字节对齐
a、存放在程序的data segment之中4、非静态成员变量 nonstatic data members
b、通过指针和对象来存取member,完全一样,不管继承或者是虚拟继承得来,全局也只存在唯一一个实例
c、静态常量成员可以在类定义时直接初始化,而 普通静态常量成员只能在.o编译单元的全局范围内初始化
a、 每一个nonstatic data member的偏移量在编译时即可获知 ,不管其有多么复杂的派生,都是一样的。通过对象存取一个nonstatic data member,其效率和存取一个C struct member是一样的。成员变量的具体分布详情参见C++内存分布
b、从对象存取obj.x和指针存取pt->x有和差异?
当继承链中有虚基类时,查找虚基类的成员变量时延迟到了执行期,根据virtual class offset查找到虚基类的部分,效率稍低
(成员变量的数据存取并没有this指针的变化)通过指针来存取成员变量会由于需要知道指向哪一种class type,所以很慢,而直接存取则不会
3.4 “继承”与Data Member
pc1_1=pc2;
*pc2_2=*pc1_1;
这一节内容很多,主要分了几个方面讨论不同情况下data member
1. 如果只有继承,没有多态,也就是没有虚函数,这里需要保证的是:“出现在derived class 中的base class subobject有其完整原样性”,因为子类的成员与基类的子对象绑在了一起,去填补空间,这样基类的子对象的原样性就会受到破坏。
2. 加上多态即虚函数后,首先是virtual table和vptr会创建出来,当然这个创建过程会影响到constructor,另外destructor也要相应修改。对于vptr的位置,不同的编译器会有不同的实现。
3. 对于多重继承,其对象的地址会指定给最左端的base class的指针,情况和单一继承相同,至于第二个或者猴急的基类的地址指定操作则需要将地址修改过
vertex3d v3d;
vertex *pv;
Point2d *p2d;
Point3d *p3d;
对于pv=&v3d的操作,内部转换为pv=(vertex*)(((char*) &v3d+sizeof(Point3d));
而对p2d、p3d赋值则不需要转换
另外也有某些编译器有不同的实现,但可以确定的是这样的class可能会有多个vptr。
4. 虚拟继承,基本思路也是引入一个新的指针,指向共享的内容。由于一般都比较麻烦,所以这里推荐的做法是virtual base class里面没有data member 每个继承虚基类的对象中都有一个指向虚基类的指针,这样能实现class的共享部分。
3.5 对象成员的效率
大概的意思是打开优化开关后,都是差不多的,只有虚拟继承的效率比较差。另外都要靠测试来检验,没有什么经验可循。
3.6 指向Data Members的指针
每个data member都是有地址的,这里把这个地址取出来,然后进行操作,另外不同编译器还有差距,会有一个相差1的不同,所以就不研究这个问题了,求取对象的其实地址,如果其定义了x,y,z,则&z的地址-z的偏移值+1即可。