Data语意学

来源:互联网 发布:龙应台我的祖国 知乎 编辑:程序博客网 时间:2024/06/03 11:10

空类不空

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、对象成员的效率





0 0