Static Data Members
程序代码片段:
class Point3d{
public:
.....
private :
float x;
static List<Point3d*> *freeList;
float y;
static const int chunkSize = 250 ;
float z ;
.....
};
每一个static Data member只有一个实例,存放在程序的Data segment之中。每次程序取用static member时,就会被内部转化为对唯一extern实例的直接参考操作。
// origin.chunkSize ==250
Point3d::chunkSize == 250;
//pt->chunkSize ==250
Point3d::chunkSize==250;
从指令执行的观点来看,这是C++语言中“通过一个指针和通过一个对象来存取member,结论完全相同”的唯一一种情况。
member其实并不在class Object之中,因此存取static members并不需要通过class Object。
但如果chunkSize是一个从复杂继承关系中继承而来的member,又当如何?或许他是一个virtual base class 的 virtual base class 的member也说不定,但是程序之中对于static members还是只有唯一一个实例,而其存取路径还是那么直接。
如果static Data member是经由函数调用,或其他某些语法而别存取呢?举个例子:
foobar().chunkSize == 250;
调用foobar()会发生什么事?下面是一种可能的转化:
(void)foobar();
Point3d::chunkSize ==250;
若取一个static Data member的地址,会得到一个指向其数据类型的指针,而不是一个指向其class member的指针,因为static member并不内含在一个class Object之中。例如:
&Point3d::chunkSize;
会获得类型如下的内存地址:
const int*;
如果两个class都声明了一个static member chunkSize,那么当它们都被放在程序的Data segment中,就会导致名称冲突。编译器的解决方法是暗中对每一个static Data member编码(name-mangling),以获得独一无二的程序识别代码。name-mangling都有两个重点:
1.一个算法,推导出独一无二的名称。
2.独一无二的名称可以轻易被推导到原来的名称。
Nonstatic Data Member
Nonstatic Data Member直接存放在每一个class Object之中。
除非经由显示的explicit或者隐式的implicit class Object,否则没有办法直接存取它们。只要程序员在一个Member function中直接处理一个Nonstatic Data Member,所谓的”implicit class Object“就会发生。例如下面这段代码:
Point3d Point3d::translate(const Point3d &pt){
x+=pt.x;
y+=pt.y;
z+=pt.z;
}
这里对于x,y,z的直接存取,事实上是由一个implicit class Object(由this指针表达)完成的。事实上这个函数的参数是:
//member function 的内部转化
Point3d Point3d::translate(const Point3d &pt,Point3d *const this){
this->x +=pt.x;
this->y +=pt.y;
this->z +=pt.z;
}
欲对一个Nonstatic Data Member 进行存取,编译器需要把class Object的起始地址加上Data Member的偏移地址(offset).
如:
origin._y = 0.0;
那么地址&origin._y将等于:
&origin+(&Point3d::_y-1);
请注意其中的-1操作。指向Data Member的指针,其offset值总是被加上1,这样可以使编译器区分出”一个指向Data Member的指针,用以指出class的第一个Member”和“一个指向Data Member的指针,没有指出任何Member”两种情况。
每一个Nonstatic Data Member的偏移位置(offset)在编译时期即可获知,甚至如果Member属于一个base class subobject也是一样的。因此存取一个Nonstatic Data Member,其效率和存取一个C struct Member或一个nonderived class的Member一样。