深度探索C++对象模型---Member Function的各种调用方式

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中调用的函数,前提是显示通过类名调用,则会被转换成非成员函数,提高效率。






你可能感兴趣的:(深度探索C++对象模型---Member Function的各种调用方式)