一、函数指针数组
前面分析函数指针,其实应该把这个函数指针数组整合到其中去,结果给忘记了。函数指针是个什么现在基本都弄明白了,那么函数指针数组是个什么呢?把数组的定义一套就可以了,其实就是一组函数指针或者说把函数指针放到了数组里。函数指针数组优势在于,可以把一些类似的动作集中于一个模块中进行操作,减少相关重复代码的操作,让代码更清晰。但是缺点也很明显,一般函数指针调试起来不如普通函数方便,特别是对于新手,跳来跳去,可能一会就花了眼。
在一些协议解析,数据转发控制,switch语句中,使用函数指针,可以使设计更灵活,更有弹性,不会因为代码的处理变化引起整个设计的变化,即使有代码的变动,基本也是只增不改。这就大大的提高了软件整体的安全性和健壮性。
有了函数指针数组,也就不得不提到,指向函数指针数组的指针,这个也没什么,其实就是再对函数指针数组取指针。下面看看例子会更清楚:
//函数指针数组
int* (*pf[2])(int * p);
//指向函数指针数组的指针
int* (*(*pf)[2])(int * p);
对于比较熟悉指针的人来说这个不是什么问题,可是不熟悉的就头大了。不要急看下面的例程会更清楚。
二、应用实例
正所谓代码之前,了无秘密,看一下具体的例程:
int f1(int d)
{
std::cout << "this is f1!" << std::endl;
return d;
}
int f2(int d)
{
std::cout << "this is f2!" << std::endl;
return d;
}
int f3(int d)
{
std::cout << "this is f3!" << std::endl;
return d;
}
// 函数指针数组
int (*funca[3])(int) = { f1, f2, f3 };
//指向函数指针数组的指针
int (*(* pfunca)[3])(int) = &funca;
void CallFuncArray()
{
int r = 0;
//调用函数指针数组,两种方式均可
std::cout << "start call func pointer array" << std::endl;
r = (*funca[0])(1);
r = (*funca[1])(2);
r = (*funca[2])(3);
r = funca[0](1);
r = funca[1](2);
r = funca[2](3);
//auto处理函数指针数组
std::cout << "start call func pointer array:use auto" << std::endl;
auto arrayp = funca;
//auto arrayp = {f1,f2,f3};//error,auto只匹配单个变量
arrayp[0](1);
//指向函数指针数组的指针
std::cout << "start call func pointer array pointer" << std::endl;
auto paf = &funca;
auto paf1 = pfunca;
r = (*paf)[0](1);
r = (*paf)[1](2);
r = (*paf)[2](3);
r = (*(*paf)[0])(1);
r = (*(*paf)[1])(2);
r = (*(*paf)[2])(3);
r = (*paf1)[0](1);
r = (*paf1)[1](2);
r = (*paf1)[2](3);
}
void do1(char *buf)
{
std::cout << "this is do1!" << std::endl;
}
void do2(char *buf)
{
std::cout << "this is do2!" << std::endl;
}
// 函数指针数组实例
void (*paEx[2])(char *) = { do1, do2 };
void PhraseData(int type, char* buf)
{
//此处就可以动态跳转
paEx[type](buf);
}
int main()
{
CallFuncArray();
return 0;
}
这种用法如果用到一些场景下还是非常不错的,可以认真的分析一下。当然把这段代码模板化也更好,大家可以尝试着搞一下。
三、总结
学习c/c++的一个痛点就是指针,指针的灵活性对于初学者和中等水平开发者,甚至是一些所谓高级开发者都感到头痛。这也是这门语言饱受诟病的地方,指针的指来指去,到最后可能没人知道他指向的是一个函数还是一个变量。而这种调用,如果没有一些辅助的安全措施,结果一定是崩溃。崩溃并不可怕,可怕的是崩溃后,啥有用的信息也没有提供。
因此,在设计中,就要尽量实行一些集中解耦处理,如果涉及到指针必须要对指针的一些用途加以限定和判断,比如在新的标准中的各种类型等的处理,数据格式的处理等等,尽量保证代码的安全性。刀是一把好刀,一定要用好。