最近我在创建一种新的棋类游戏,其中在限定走子规则上,需要使用类内的函数指针,以数组的形式。事实上在我上一个win32游戏项目中,曾经使用过函数指针;所以我以为在这一次对函数指针的使用上我会得心应手水到渠成,可编译器狠狠的打了我几个耳光(各种报错,所幸通过不断的摸索最后使用成功),于是我决定写下这篇博客,以图巩固一下对类函数指针的认识。
为了简化,关于类的名称就叫A吧,先定义一个类的头文件,如下所示:
#include <iostream>
using namespace std;
class A
{
public:
A(int n);
~A();
/*下面就是我们的类函数指针的声明
首先,众所周知函数指针的声明前面要用圆括号括起来,
而类函数指针在前面还要加一个类名与域操作符【::】,
表示这种函数指针只能指向这个类中的某些函数;
中括号和3表示这是一个函数指针数组,最后那个圆括号
表示参数列表,要和被指向的函数参数列表一致才行*/
void (A:: *pfun[3])();
void show(int i);//之所以加上这个函数,是为了展示【->*】的用法
private:
void fun1();//第一个函数指针要指向的函数;
void fun2();//同上,是第二个
void fun3();//第三个
};
然后是我们的cpp文件定义:
#include "A.h"
A::A()
{
/*类函数指针的赋值要严格如下所示
前面的【&】与类域操作符都是必不可少的*/
pfun[0] = &A::fun1;
pfun[1] = &A::fun2;
pfun[2] = &A::fun3;
/*下面这个就是非法的*/
//pfun[2] = A::&fun3;
}
void A::show(int i)
{
if(i < 3)
(this ->* pfun[i])();//这里必须要加上this,因为【->*】是一个操作符,前面必须要有对象
}
void A::fun1()
{
cout << "fun1:hello world!" << endl;
}
void A::fun2()
{
cout << "fun2:i'm xiaobiao." << endl;
}
void A::fun3()
{
cout << "fun3:谢谢您的阅读!" << endl;
}
A::~A()
{
}
最后是我们的源文件定义:
#include "A.h"
int main()
{
A a;
for (int i = 0; i < 3; i++)//这个是错误的使用方式,编译器不会报错
a.pfun[i];
cout << "上面显示内容了吗?没有吧,这是因为我们使用了错误的方式,下面的才是正解!" << endl;
for (int i = 0; i < 3; i++)//这个才是正确的使用方式
(a .* (a.pfun[i]))();
a.show(2);
return 0;
}
其中在源文件中,注意看第9行代码,那个【.*】实际上是一个操作符,它俩的出现意味着要调用类函数指针了(您可以试着在它俩中间加一个空格什么的,相信编译器会报错);而且这行出现了两个a,第一个a是配合【.*】使用的调用对象,而后面那个a意思是使用这个对象里面的函数指针值;也许我说的有点晕,如果读者朋友有心,可以创建两个A对象x和y,然后让x和y的函数指针数组里面的值不一样,比如x里面的pfun[0]指向的是fun1函数,而y里面的pfun[0]指向的却是fun3函数,然后用这样的代码
(x.* (y.pfun[i]))();
测试一下,相信您会有所启发的