第三章:Data语意学(The Semantices ofData)

来源:互联网 发布:程序员客栈好接单吗? 编辑:程序博客网 时间:2024/06/01 10:15

第三章:Data语意学(The Semantices ofData)


1、Data绑定:Class的data绑定发生在整个Class声明完(右大括号出现)。因此当data member 与全局data同名时,会选择绑定到data member。


2、data member 的布局layout: class 中nonstatic datamembers 的声明顺序与其在class object 中的布局顺序同,中间插入的static data members 则放到整个程序的globl section 中(被视为一个globl 变量,但在class的声明范围内可见!),与个别的object 无关。


3、注意:object 的layout 只要求较晚出现的nunstatic data members 由较高的地址。并不保证data  members 是连续存放的,期间可能插入其他,比如边界填充。当有vitual 时会为object 添加vptr指针,一帮放在所有members 的最后,也有编译器放在最前端。


4、data member的存取:对static datamembers 在不管继承体系多复杂,在整个程序中只有一份实体(就算一个对象都没有,依然存在一份实体)。  因此对staticdata  members取地址,得到的是一个相应数据类型的指针,而不是class member 的指针。即:派生类对象与基类对象共享基类的静态数据成员


5、当多个class声明了一个名字类型相同的static data members 时,在程序的data segment 编译器将会采用name-magling 技术对每一个data member具有独一无二的程序识别代码。


6、对nonstatic data member 的存取通过(对象的起始地址+该变量的偏移量-1)直接操作。(对没有vitual base class 时)


 7、当在由虚基类的继承体系中:Class A; class a:public A;

  a aa;//对象aa   a* p; //对象指针p 

则 aa.datamem;  p->datamem;       

 当存取由虚基类继承而来的data member时,会有重大差异:对象指针会有多态性问题,因此存取操作一定在执行进行,而直接由对象名存取时直接在编译期就可以完成。


8、在无虚函数的继承体系中:每一个drivedclass都会完整的包含其直接base class的全部data members (包括基类用于边界填充的部分,如果派生类由新添的data members,则放到其基类成员的最后(包括边界之后!!)),因此会因为每一级的边界填充而使得继承体系中布局膨胀(各级的边界填充累积) 

    

9、单一继承并含有虚拟函数:继承一个Vptr指针。(Vptr一般放在数据成员的末端)


10、指向data member的指针:取非静态成员的地址:p=&a;//得到时该成员在该object的偏移量(+1??,注意如果有vptr时,考虑其放的位置)。

 

11、类体中的数据成员的声明前加上static关键字,该数据成员就成为了该类的静态数据成员。和其他数据成员一样,静态数据成员也遵守public/protected/private访问规则。同时,静态数据成员还具有以下特点: 
1).静态数据成员的定义。 
静态数据成员实际上是类域中的全局变量。所以,静态数据成员的定义(初始化)不应该被放在头文件中。 
其定义方式与全局变量相同。举例如下: 
xxx.h文件 
class base{ 
private: 
static const int _i;//声明,标准c++支持有序类型在类体中初始化,但vc6不支持。 
}; 
xxx.cpp文件 
const int base::_i=10;//定义(初始化)时不受private和protected访问限制. 

注:不要试图在头文件中定义(初始化)静态数据成员。在大多数的情况下,这样做会引起重复定义这样的错误。

 

 静态成员不可在类体内进行赋值,因为它是被所有该类的对象所共享的。你在一个对象里给它赋值,其他对象里的该成员也会发生变化。为了避免混乱,所以不可在类体内进行赋值。只能在类体外进行初始化。

    一般形式:

    数据类型类名::静态数据成员名=初值

    注意:不能用参数初始化表对静态成员初始化。一般系统缺省初始为0

0 0