***非静态成员函数(Nonstatic Member Functions)***
C++的设计准则之一就是: nonstatic member function至少必须和一般的nonmember function有相同的效率。也就是说,如果我们 要在以下两个函数之间作选择:
float magnitude3d(const Point3d *this) { ... }
float Point3d::magnitude3d() const { ... }
那么选择member function不应该带来 什么额外负担。因为编译器内部已将“member函数实体”转化为对等的“nonmember函 数实体”。下面是magnitude()的一个nonmember定义:
float Pointer3d::magnitude() const
{
return sqrt(_x*_x + _y*_y + _z*_z);
}
// 内部转化为
float magnitude_7Point3dFv(const Point3d *this) //已对函数名称进行 “mangling”处理
{
return sqrt(this->_x*this->_x + this- >_y*this->_y + this->_z*this->_z);
}
现在,对该函数的每一个调 用操作也都必须转换:
obj.magnitude();
// 转换为
magnitude_7Point3dFv (&obj);
对于class中的memeber,只需在member的名称中加上class名称,即可形成 独一无二的命名。但由于member function可以被重载化,所以需要更广泛的mangling手法,以提供绝对 独一无二的名称。其中一种做法就是将它们的参数链表中各参数的类型也编码进去。
class Point {
public:
void x(float newX);
float x();
...
};
// 内部转化为
class Point {
void x_5PointFf(float newX); // F表示function,f表示其第一个参数类型是float
float x_5PointFv(); // v表示其没有参数
};
上述的mangling手法可在链接时期检查出任何不正确的调用操作,但由于编码 时未考虑返回类型,故如果返回类型声明错误,就无法检查出来。
***虚拟成员函数(Virtual Member Functions)***
对于那些不支持多态的对象,经由一个class object调用一个virtual function,这种操作应该总是被编译器像对待一般的nonstatic member function一样地加以决议:
// Point3d obj
obj.normalize();
// 不会转化为
(*obj.vptr[1]) (&obj);
// 而会被转化未
normalize_7Point3dFv(&obj);
***静态 成员函数(Static Member Functions)***
在引入static member functions之前,C++要求所有 的member functions都必须经由该class的object来调用。而实际上,如果没有任何一个nonstatic data members被直接存取,事实上就没有必要通过一个class object来调用一个member function.这样一来便 产生了一个矛盾:一方面,将static data member声明为nonpublic是一种好的习惯,但这也要求其必须 提供一个或多个member functions来存取该member;另一方面,虽然你可以不靠class object来存取一 个static member,但其存取函数却得绑定于class object之上。
static member functions正是 在这种情形下应运而生的。