空类不空
class A
{
}
sizeof(A) == 1.
原因:如果A的sizeof是0,A a1, A a2
a1和a2的地址如何处理?&a1是什么呢?所以编译器为空类会插入一个字节。
1、Data Member的绑定
inline函数是会在整个class声明出现之后才开始进行分析。不会出现成员变量在inline函数后面而找不到定义。
2、Data Member的布局
C++标准要求,在同一个access section(public, private ,protected)中,member的排列只需符合“较晚出现的members在class object中较高的地址”
如下
class Point3d
{
public:
private:
float x;
float y;
float z;
private:
float x2;
float y2;
float z2;
}
C++标准只要求,x,y,z的地址顺序z>y>x,z2>y2>x2。x和x2的顺序则不做要求,或则在z,y,x中间插入其它内容也不做要求。如vptr,不过编译器一般会将vptr插入到所有member的最后面。
把8个变量申明在一个access section或则申明8个access section各方一个变量。大小都是一样的
3、Data Member的存取
3.1、static data member
每一个static data member只有一个实体,放在程序的data segment之中。取一个static data member的地址,会得到其指向static的真正地址,而不是指向类成员的指针。
如果两个类都申明一个static member freelist,编译不会导致名字冲突。因为编译器给每个static会进行改名,通过加上类名,命名空间等(与函数类似)。
3.2、nonstatic data member
存储每个非静态成员变量,编译器需要把类对象的起始地址加上成员变量的偏移量。我们取非静态成员变量的地址,实际上获取的是它的一个偏移量。
偏移量在编译器就能够确定(成员变量的顺序),即存储非静态成员变量的效率和存取一个C结构的member是一样的。
4、Data member碰上继承
4.1 只要继承不要多态
A继承自B,如果A的大小是3个字节,实际会进行4字节对齐。B自身大小为1个字节,C++也不会将A,B合并成4字节,而是让A继续保持4字节,B再次对齐,这样出现8字节的情况。
如果将B直接填充到A的最后一位,在赋值的时候
*B = *A,这样会把B的值覆盖掉,而不是保留原有的值,只覆盖A的信息。
4.2 加上多态
4.3 多重继承
class A
class B:
class C: public A, public B
在内存布局中
A
B
C
C* pc;
A* pa = pc。两者地址是一样的。C包含了A,B的内容,起始地址就是A的地址。
B* pb = pc。两者的地址就不同了,因为B在中间那部分,得到的应该是A的地址加上A的大小
5、对象成员的效率