类非静态成员函数的转换
c++设计的准则之一就是非静态成员函数必须要和普通的非成员函数有着相同的效率,也就是说对于如下的两个函数,其调用的开销应该是一样的。编译器为了得到这种效果,其在内部会将成员函数转换为一个对等的非成员函数实例。
double Point3d::magnitude() const(); //Point3d的成员函数
double magnitude(const Point3d *ptr); //非成员的全局函数
其转换过程的步骤如下:
- 改写函数的
signature
(函数原型),首先会安插一个额外的参数到成员函数(member function)中,用以提供一个对成员数据的存取管道,该额外参数也被称为this
指针:
// no-const no-static 成员函数扩张
double Point3d::magnitude();
// 扩张为 double Point3d::magnitude(Point3d *const this);
// no-const no-static 成员函数扩张
double Point3d::magnitude() const;
// 扩张为 double Point3d::magnitude(Point3d *const this);
- 将每一个对非静态数据成员的存取操作,改为经由
this
指针来存取,例如magnitude
的代码即可能被扩张为如下:
double Point3d::magnitude(Point3d *const this) {
return sqrt(this->x * this->x + this->y * this->y + this->z * this->z);
}
- 将该函数签名通过
mangling
处理,使得其在程序中称为独一无二的全局函数签名,编译器的处理结果有可能如下所示:
extern magnitude_7Point3dFv(register Point3d *const this);
经过上述三步以后,这个成员函数即被转换为了一个全局函数,而对这个全局函数的调用操作也必须转换:
obj.magnitude();
//转换后: magnitude_7Point3dFv(&obj);
prt->magnitude();
//转换后: magnitude_7Point3dFv(ptr);