1、非静态成员函数转化为非成员函数
c++ 设计准则之一就是:非静态成员函数至少和非成员函数有相同的效率。
也就是说下面两个函数具有相同的效率:
float magnitude(const Point3d * this){...};
float Point3d::magnitude(){...};
以
float Point3d::magnitude()
{
return sqrt(x * x + y * y + z * z);
}
为例。
magnitude函数被转化为非成员函数的步骤如下:
1.1 改写函数原型,在第一个参数的位置安插this指针。
float Point3d::magnitude( Point3d * const this);
如果成员函数是const 则变成
float Point3d::magnitude(const Point3d * const this);
1.2 将对非静态成员的存取改为经this指针存取:
return sqrt(this->x * this->x + this->y * this->y + this->z * this->z);
1.3 将成员函数重写成一个外部函数,并处理函数名:
magnitude() -> *magnitude_7Point3dFv(Point3d const this)
obj.magnitude(); -> magnitude_7Point3dFv(&bj);
ptr->magnitude(); -> magnitude_7Point3dFv(ptr);
2、 名称的特殊处理(Name Mangling)
2.1 数据成员名称的处理
一般情况下,会在成员名称后加上类名。
例:
class Bar
{
public:int ival;
};calss Foo : public Bar
{
public:int ival;
};
Foo会被处理成下面这样
calss Foo
{
public:int ival_3Bar; //父类的成员int ival_3Foo; //Foo的成员
};
2.2 成员函数名称的处理
因为c++支持函数重载,所以在处理成员函数名称的时候加上了参数列表。
下面是Point类的定义:
class Point
{
public:
void x();
float x(float)
};
下面是处理后的Point类
class Point
{
public:
void x_5PoitFv();
float x_5PoitFf(float)
};
3、 虚拟成员函数
加入我们有一个Point类如下:
class Point
{
public:virtual void normalize();
}
那么下面的调用
ptr->normalize();
会被转化为
(*ptr->vptr[1])->(ptr);
- vptr表示指向虚函数表的指针。
- 1是normalize在虚表中的索引值
- 第二个 ptr 表示this指针
4、静态成员函数
如果上面Point中normalize函数是静态函数,则别转换为一般的非成员函数:
obj.normalize() -> normalize_5PointSFv()
ptr->normalize() -> normalize_5PointSFv()
4.1、静态成员函数的特性
- 它不能够直接存储非静态成员。
- 他不能声明为const、virtual 或volatile。
- 他不需要经由类对象调用
5、指向成员函数的指针
如有Point类如下:
class Point
{
public:
float get_x();
void set_x(float)
};
下面定义指向get_x和set_x函数的指针:
float (Point::*f_get_x)() = &Point::get_x;void (Point::*f_set_x)(float) = &Point::set_x;