通过指针和通过对象存取成员
2012-5-30(恒大和东京FC比赛那天)
在书中,提到了一个问题
Point origin ////////////先前定义一个Point的类
origin.x
origin->x 这两种用法到底有什么区别,哪种的耗费较大
1. 如果 x为静态成员,那么x在编译的时候已经申请好了内存,这个时候x其实不属于orgin这个对象,而是属于整个类,
这是无论哪种操作,都是直接转换为
Point::x 这个操作。
所以在这种情况下,两种操作没有差别。
2. 如果x为nonstatic 数据成员,那么data member 直接存放在每一个class object中,
那么,两者的差别就主要在于取数据时候的地址的偏移产生。
对一个nonstatic data member进行存取操作,编译器需要把class object的起始地址加上data member的偏移位置 (offset)。
如: origin.y=0.0;
那么:地址&origin.y 等于 &origin+(&Point::y - 1);(书上上,这里-1是因为只想data member的指针,其offset
值总是被加上1,用于区分“一个指向data member 的指
针,用以指出class 的第一个member”和“一个指向
data member的指针,没有指出任何member”)
如果member的偏移地址在编译的时候可以获得,那么就可以两种方法的效率都一样的。
origin.x无论他是继承父类,还是多态,它的members的offset位置在编译的时期就固定了,
origin->x就不同,如果他是一个派生类,并且它的继承结构中有一个virtual base class,并且被存取的member(如本例中的 x)是一个村该virtual base class 继承而来的member,那么他的offset 就是在运行时才确定,需要一个额外的间接引导,此时,这种方法的效率就会低一些.其实也就是多态的性质产生的不同