指向函数的指针定义:
int (*fp) (float);
(*fp) 的圆括号使得编译器正确判断定义,没有圆括号,这个表达式就是一个返回 int *的函数 int * fp (float)
同样,成员函数指针也需要圆括号:
class Simpe{
public:
int f(float) const{return 1;}
};
int (Simple::*fp)(float) const;
int (Simple::*fp2)(float)const = &Simple::f;
int main(){
fp = &Simple::f;
}
成员指针可以在创建或者其他时候被初始化。
成员函数指针的调用必须用 .* 或者 ->* 的方式。类似 int re = fp(9.0) 是不允许的。必须是 : int re = (pSObj->*fp)(9.0) 注意:这里的括号是必须的。
1 #include <iostream>
2 using namespace std;
3
4 class Widget{
5 public:
6 void f(int)const{cout<<"Widget::f()\n";}
7 void g(int)const{cout<<"Widget::g()\n";}
8 void h(int)const{cout<<"Widget::h()\n";}
9 };
10
11 int main(){
12 Widget w,*wp = &w;
13 w.f(100);
14
15 void (Widget::*fp)(int) const;
16 fp = &Widget::f;
17 (wp->*fp)(1);
18 fp = &Widget::g;
19 (wp->*fp)(1);
20 return 0;
21 }
上面是一个动态改变指针内容的例子。
为了更加简化用户使用,可以使用成员指针作为内部执行机制的一部分
1 #include <iostream>
2 using namespace std;
3 class Widget{
4 void f(int)const {cout<<"Widget::f()\n";}
5 void g(int)const {cout<<"Widget::g()\n";}
6 void h(int)const {cout<<"Widget::h()\n";}
7 enum{cnt = 3};
8 void (Widget::*fptr[cnt])(int) const;
9 public:
10 Widget(){
11 //注意这里需要写完整的类名,并不因为在内部而可以省略
12 fptr[0] = &Widget::f;
13 fptr[1] = &Widget::g;
14 fptr[2] = &Widget::h;
15 }
16 void select(int i,int arg){
17 if(i > 0 || i < cnt)
18 (this->*fptr[i])(arg);//注意这里的括号和this都是不可少的
19 }
20 int count(){return cnt;}
21 };
22
23 int main(){
24 Widget w;
25 for(int i=0;i<w.count();i++)
26 w.select(i,i*10);
27
28 return 0;
29 }
总结:
- 记住这种数组写法: void (Widget::*fptr[cnt]) (int)
- 在内部定义时不要省略类名: fptr[0] = &Widget::f
- 在内部调用方法时不要省略对象this或者忘记括号 : (this->*fptr[0])(args)