這裡不是要講函數指標的概念,也不是深入分析函數指標,我不是專家,只是一個普通程式員。通過執行個體來和大家討論討論函數指標的用法,因為接觸的許多項目都用了函數指標,所以有必要自己寫一個樣本熟悉和總結下
通常項目中使用函數指標是為了方便的調用函數,減少代碼的複雜度,便於維護等等,所以先將各個函數儲存起來,比如用索引值對的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;}