这里不是要讲函数指针的概念,也不是深入分析函数指针,我不是专家,只是一个普通程序员。通过实例来和大家讨论讨论函数指针的用法,因为接触的许多项目都用了函数指针,所以有必要自己写一个示例熟悉和总结下
通常项目中使用函数指针是为了方便的调用函数,减少代码的复杂度,便于维护等等,所以先将各个函数存储起来,比如用键值对的Hash数据结构来将相关函数的名字和指针存储起来,用的时候根据函数名,取出相应的函数指针,然后就可以调用了
首先啰嗦下如何定义一个函数指针
int (*f) (int x); /* 声明一个函数指针 */
相对的,我写了一个宏定义:typedef void (* PFUNC_EXAMPLE)(void *pobj, char *data, int length);
如果说这个函数的一般定义,是这样的void FUNC_EXAMPLE(void
*pobj, char *data, int length);
可以比较下两者的区别
要将函数指针存储出来,就要使用hash数据结构,这里我使用的是STL的map
头文件是#include <map>
我写了一个宏定义:typedef map<char *, PFUNC_EXAMPLE> UDT_MAP_CHAR_PFUNC_EXAMPLE;
现在写一个我们要调用的函数,我写了,根据实际情况,可以写很多个
class CFuncPointEx
{
public:
static void Func_A(void *pobj, char *data, int length);
static void Func_B(void *pobj, char *data, int length);
static void Func_C(void *pobj, char *data, int length);
};
实现很简单
void CFuncPointEx::Func_A(void *pobj, char *data, int length)
{
printf("Func_A\n");
}
void CFuncPointEx::Func_B(void *pobj, char *data, int length)
{
printf("Func_B\n");
}
void CFuncPointEx::Func_C(void *pobj, char *data, int length)
{
printf("Func_C\n");
}
然后写一个管理类
class CFuncManager
{
public:
CFuncManager(void);
void RegisterFunc(char *func_name, PFUNC_EXAMPLE pfunc_ex);
PFUNC_EXAMPLE GetFunc(char *func_name);
private:
UDT_MAP_CHAR_PFUNC_EXAMPLE pfunc_map;
};
实现
void CFuncManager::RegisterFunc(char *func_name, PFUNC_EXAMPLE pfunc_ex)
{
pfunc_map.insert(pair<char *, PFUNC_EXAMPLE>(func_name, pfunc_ex));
}
PFUNC_EXAMPLE CFuncManager::GetFunc(char *func_name)
{
return pfunc_map.find(func_name)->second;
}
然后在主函数写测试代码
CFuncManager cfunc_m;
cfunc_m.RegisterFunc("Func_A", &CFuncPointEx::Func_A);
cfunc_m.RegisterFunc("Func_B", &CFuncPointEx::Func_B);
cfunc_m.RegisterFunc("Func_C", &CFuncPointEx::Func_C);
(cfunc_m.GetFunc("Func_A"))(NULL, NULL, 0);
(cfunc_m.GetFunc("Func_B"))(NULL, NULL, 0);
(cfunc_m.GetFunc("Func_C"))(NULL, NULL, 0);
结果不出意外,应该是打印
Func_A
Func_B
Func_C
通过这个实例,相比可以体会到函数指针的用法,至于用途,我看过的很多项目多多少少都用过函数指针
这次总结就到这里
最后发下源代码
//FuncPointEx.h #ifndef __FUNCPOINTEX__H__ #define __FUNCPOINTEX__H__ #endif #include <map> using namespace std; typedef void (* PFUNC_EXAMPLE)(void *pobj, char *data, int length); typedef map<char *, PFUNC_EXAMPLE> UDT_MAP_CHAR_PFUNC_EXAMPLE; class CFuncPointEx { public: static void Func_A(void *pobj, char *data, int length); static void Func_B(void *pobj, char *data, int length); static void Func_C(void *pobj, char *data, int length); }; class CFuncManager { public: CFuncManager(void); void RegisterFunc(char *func_name, PFUNC_EXAMPLE pfunc_ex); PFUNC_EXAMPLE GetFunc(char *func_name); private: UDT_MAP_CHAR_PFUNC_EXAMPLE pfunc_map; };
// FuncPointEx.cpp : 定义控制台应用程序的入口点。 // #include "stdafx.h" #include "FuncPointEx.h" void CFuncPointEx::Func_A(void *pobj, char *data, int length) { printf("Func_A\n"); } void CFuncPointEx::Func_B(void *pobj, char *data, int length) { printf("Func_B\n"); } void CFuncPointEx::Func_C(void *pobj, char *data, int length) { printf("Func_C\n"); } CFuncManager::CFuncManager(void) { } void CFuncManager::RegisterFunc(char *func_name, PFUNC_EXAMPLE pfunc_ex) { pfunc_map.insert(pair<char *, PFUNC_EXAMPLE>(func_name, pfunc_ex)); } PFUNC_EXAMPLE CFuncManager::GetFunc(char *func_name) { return pfunc_map.find(func_name)->second; } int _tmain(int argc, _TCHAR* argv[]) { CFuncManager cfunc_m; cfunc_m.RegisterFunc("Func_A", &CFuncPointEx::Func_A); cfunc_m.RegisterFunc("Func_B", &CFuncPointEx::Func_B); cfunc_m.RegisterFunc("Func_C", &CFuncPointEx::Func_C); (cfunc_m.GetFunc("Func_A"))(NULL, NULL, 0); (cfunc_m.GetFunc("Func_B"))(NULL, NULL, 0); (cfunc_m.GetFunc("Func_C"))(NULL, NULL, 0); system("pause"); return 0; }