您的位置:首页 > 编程语言 > C语言/C++

深度探索C++对象模型-指向Data Members的指针

2015-06-19 14:40 691 查看
class Point3d{
public:
virtual ~Point3d();
//....
protected:
static Pointed origin ;
float x,y,z ;
};


每一个Point3d class object 含有三个坐标值,依序为x、y、z,以及一个vptr。至于satic data member origin,则将放在class object之外。唯一不能确定的就是vptr的位置,根据不同的编译器厂商,可能放在最起始处、尾端或者各个member之间(但是,编译器厂商不是把vptr放在object的头,就是object的尾端)。

那么,取某个坐标成员的地址,代表什么意思?

&Point3d::z


上述的操作得到的z坐标在class object中的偏移值(offset),最低限度其值将是x,y大小的总和,*因为C++ 语言要求同一个access level中的members的排列应该与其声明顺序相同。*

如果vptr放在对象的尾端,三个坐标值在对象布局中的offset分别是0,4,8。如果vptr放在对象的起始处,三个坐标值在对象布局中的offset分别是4,8,12.然而你若去取data members的地址,传回的值总是多1,也就是1,5,9或者5,9,13等等。

使用cout不能输出
printf("&Point3d::x=%p\n",&Point3d::x);
printf("&Point3d::x=%p\n",&Point3d::x);
printf("&Point3d::x=%p\n",&Point3d::x);


为什么传回的值总是多1呢??

原因就是为了让区分一个“没有指向任何data member “的指针,和一个指向”第一个data member”的指针。

float Point3d::*p = 0 ;
float Point3d::*p1 = &Point3d::x ;


为了区分p与p1,每一个真正的member offset值都被加上1.在真正使用该值以指出一个member之前,请先减掉1。

取一个nonstatic data member 的地址将会得到 它在class 中的offset ,取一个绑定真正class object 身上的data member的地址,将会得到该member 在内存中真正的地址。把

&origin.z //float *

所得结果结果减 z的偏移值(相对于origin起始值),再加1,就得到了origin起始地址。

float Point3d::*ax = &Point3d::x ;
origin.*ax == origin.x;
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: