已知下面这段代码
Point3d origin,*pt = &origin;
存取data member有什么区别
origin.x = 0.0;
pt->x = 0.0;
Static Data Members
Static data members被编译器提出于class之外,被视为一个global变量。
若X是一个Static data members,则
origin.x = 0.0;
pt->x = 0.0;
//被转化为
Point3d::x =0.0//两个一样
取一个Static data members的地址,会得到一个指向其数据类型的指针,而不是一个指向class member的指针。如:
&Point3d::chunkSize;
//会得到类型如下的地址
const int*;
如果两个class声明了名字相同是Static data members,会导致data segment名字冲突。编译器的解决方法是暗中对Static data members进行编码,以获得一个独一无二的名字,并可以轻易的推倒回原来的名字。
Nostatic Data Members
Nostatic data members存放在每一个class object 中。经由显示或隐式(implicit)的class object来存取他们。只要在member function中直接处理Nostatic data members,所谓的implicit class object就好发生。
Point 3d point3d::translate(const Point3d &pt){
x+ = pt.x;
}
经由implicit class object转化为
Point 3d point3d::translate(Point3d *const this,const Point3d &pt){//添加了this指针
this->x+ = pt.x;
}
若对Nostatic data members进行存取操作,编译器需要把class object 的起始地址加上data member的offset。如:
origin.y = 0.0;
&origin + (&Point3d::y - 1);//注意其中的-1操作
注意其中的-1操作。指向data member的指针,其offset值总是被加1,这样可以使编译系统区分出“一个指向data member的指针,指出class的第一个member”和“一个指向data member的指针,没有指出任何member“两种情况。
每一个Nostatic data members的offset在编译时期即可获知,存取效率和存取C struct member一样。
当Point3d是一个derived class ,其继承结构中有一个virtual base class,并且被存取的member(如x)是从该virtual base class继承而来的时候,我们不能确定pt指向哪一种class type,所以需要一个间接引导,如果使用origin就不会有问题。