int (Point::*funcptr)() const = &Point::getX; // 定义成员函数指针并初始化
void (*funcptr)() = Point::showCount; // 定义一个指向函数的指针,指向类的静态成员函数
在书上的例子中,有以上两条语句。可以发现,指向成员函数的指针,当指向普通成员函数时,需要使用&;指向静态成员函数时,不需要使用&。造成这一现象的原因是C++中关于左值的规定。
在C/C++中,具有函数类型的表达式称为函数指示符,例如函数名或者对函数指针的解引用。由于C中的左值性反映的是数据抽象而不是操作抽象,因此C中的函数指示符既不是左值也不是右值,这个观念也在函数到指针的转换条款中得到体现,函数到指针的转换条款仅指出转换结果是一个指针,但没有指出结果的左值性。到了C++,这种观念发生了变化,C++认为,既然左值性是表达式的属性,作为初等表达式的函数指示符却没有左值性是没有道理的,同时鉴于赋予函数指示符左值性并没有坏处,因此C++中的左值也包括函数指示符。要注意的是,函数左值不包括非静态成员函数,这是因为非静态成员函数的指针与普通指针是很不相同的,C++标准出于强调两者差异的需要,硬性规定非静态成员函数的左值不能获得,从而禁止了非静态成员函数的左值转换。
因此非静态成员函数不存在隐式左值转换,即不存在像常规函数那样的从函数到指针的隐式转换,所以必须在非静态成员函数前使用&操作符才能获得地址。