Member的各种调用方式
Point3d obj; Point3d *ptr = &obj; obj.normalize(); ptr->normalize();按函数为非静态成员函数,静态成员函数,virtual函数讨论
1 非静态成员函数:被编译器在内部转化为对等的非成员函数实例,调用并不会有什么额外负担,转化分下面3个步骤
(1)改写函数原型,以安插一个额外的参数到成员函数中,是为了使用类对象调用此函数,就是将函数的第一个参数设置为this指针。
(2)对每个非静态成员的存取操作,改为经由this指针的存取
(3)将成员函数重写成一个外部函数,函数名经过“mangling”处理,成为独一无二的词汇
将上面两个函数进行转换后的形式可能是下面:
normalize__7Point3dFv(&obj); normalize__7Point3dFv(ptr);ptr与obj都表示this指针。
2 静态成员函数:也将转化为一般的非成员函数调用。
静态成员函数的特性(无this指针):
(1)不能够直接存取类中的非静态成员
(2)不能被声明为const , volatile或virtual
(3)不需要经由class object才被调用,可以经过类名调用
所以如果是静态成员函数,可能如下:
normalize__7Point3dFv(); normalize__7Point3dFv();
如果取一个静态成员函数的地址,获得的是其在内存中的位置,即真实地址你,且因为没有this指针,地址类型是一个非成员函数指针,而不是成员函数指针。
所以对于上面两中情况,函数调用会直接变为一个经过mangling处理的非成员函数调用,区别是非静态成员将添加一个this参数,而静态成员的不填加新的参数。
3 虚成员函数
通过类对象的指针调用的情况,可能被转化为下面的情况
(*ptr->vptr[1])(ptr)vptr是由编译器产生的指向虚函数表的指针,安插在每一个有虚函数,或继承了虚函数的类的对象中,事实上也会被mangled。
1 表示virtual table slot的索引值,关联到normalize函数
第2个ptr表示this指针。
如果normalize函数中又调用了一个同一个类中的虚函数virtual float Point3d::magnitude(),则因为已经对normilize由虚拟机制决议妥当,所以这个虚函数可以被显示调用,Point3d::magnitude,而且这个决议方式会和上面两种一样,被转换成一个非静态成员的方式,可以压制虚拟机制,提高效率。
virtual float Point3d::magnitude(); float mag = magnitude__7dPoint3dFv(this);如上,magnitude()表示同一个类中的虚函数normalize中调用的函数,前提是显示通过类名调用,则会被转换成非成员函数,提高效率。