上次文发了一个基于类成员函数指针实现的一个消息处理框架,这次用boost的function实现,比那个要简单灵活很多;
今天介绍的这个示例代码,算是一个消息处理框架吧,用于说函数对象function与bind的基本用法;
首先介绍一下function与函数指针的区别:
函数指针:只能指向静态函数,如果要指向类的成员函数就有一定的难度(也可以实现,上文中使用的成员函数指针)
function:函数对象,这个比较灵活,即可以当做函数指针用,也可以存储类的成员函数,类似于成员函数指针;
关于bind,这里使用主要是用于将成员函数转换为函数对象;
处理框架类:
//process_data.h
#include <iostream> #include <map> #include "public.h" #include <boost/bind.hpp> #include <boost/function.hpp> using namespace std; class CDataProcess; //typedef int (CDataProcess::*DataMsgAction)(void *, int); //boost bind def typedef boost::function<int(string,const void *, int)> MsgProcFunc; class CDataProcess { private: map<string,MsgProcFunc > devCmdActionMap; //用于存储消息命令字与处理函数对象 protected: CDataProcess(); ~CDataProcess(); static CDataProcess *m_instance; public: static CDataProcess *getInstance(); int registProcHandle(string cmd, MsgProcFunc handle); //注册消息处理函数对象 int processDataFunction(string cmd, const void *pData, int iDataLen);//消息处理 };
//process_data.cpp
#include "public.h" #include "process_data.h" #include <stdio.h> /***************************************************************************** Prototype : CDataProcess.CDataProcess Description : 构造函数 Input : None Output : None Return Value : History : 1.Date : 2016/1/29 Author : fens Modification : Created function *****************************************************************************/ CDataProcess::CDataProcess() { } /***************************************************************************** Prototype : CDataProcess.~CDataProcess Description : 析构函数 Input : None Output : None Return Value : History : 1.Date : 2016/1/29 Author : fens Modification : Created function *****************************************************************************/ CDataProcess::~CDataProcess() { } /***************************************************************************** Prototype : CDataProcess.registProcHandle Description : 注册命令字处理函数对象 Input : string cmd MsgProcFunc handle Output : None Return Value : int History : 1.Date : 2016/1/29 Author : fens Modification : Created function *****************************************************************************/ int CDataProcess::registProcHandle(string cmd,MsgProcFunc handle) { map<string,MsgProcFunc>::iterator iter = devCmdActionMap.find(cmd); if ( iter == devCmdActionMap.end() ) { devCmdActionMap[cmd] = handle; return 0; } else { printf("%s in %s, cmd: %s, alreay in the map\n",PRO_NAME, _FUN_, cmd.c_str()); } return 0; } /***************************************************************************** Prototype : CDataProcess.processDataFunction Description : 数据处理 Input : string cmd const void *pData int iDataLen Output : None Return Value : int History : 1.Date : 2016/12/28 Author : fens Modification : Created function *****************************************************************************/ int CDataProcess::processDataFunction(string cmd, const void *pData, int iDataLen) { map<string,MsgProcFunc>::iterator iter = devCmdActionMap.find(cmd); if ( iter != devCmdActionMap.end() ) { return iter->second(cmd,pData, iDataLen); } else { printf("%s in %s, not find cmd: %s func\n",PRO_NAME, _FUN_, cmd.c_str()); } return -1; } /***************************************************************************** Prototype : CDataProcess.getInstance Description : 获取一个实例 Input : None Output : None Return Value : CDataProcess History : 1.Date : 2016/1/29 Author : fens Modification : Created function *****************************************************************************/ CDataProcess *CDataProcess::getInstance() { if (0 == m_instance) { m_instance = new CDataProcess(); } return m_instance; } CDataProcess * CDataProcess::m_instance = 0;
//main.cpp
#include <iostream> #include <stdio.h> #include "process_data.h" using namespace std; int printHelpInfo(string cmd, const void *pData, int dataLen) { cout <<"-----------------------------------"<<endl; cout <<"help info:"<<endl; cout <<"help: print this info."<<endl; cout <<"ver : print this demo ver."<<endl; cout <<"test: process test class func cmd."<<endl; cout <<"q : exit."<<endl; cout <<"-----------------------------------"<<endl; return 0; } int printVer(string cmd, const void *pData, int dataLen) { cout <<"in printVer, ver 1.0.0"<<endl; return 0; } class testDataProc { public: int TestDataProcFunc(string cmd, const void *pData, int dataLen) { cout << "in testDataProc::TestDataProcFunc, process cmd "<<cmd<<endl; return 0; } }; int main(int argc, char **argv) { //静态函数注册 CDataProcess::getInstance()->registProcHandle("help", printHelpInfo); //注册help命令处理函数 CDataProcess::getInstance()->registProcHandle("ver", printVer); //注册版本ver命令处理函数 //测试类成员函数注册 testDataProc testProcObj; //这个是注册一个函数对象,test命令 CDataProcess::getInstance()->registProcHandle("test",boost::bind(&testDataProc::TestDataProcFunc, testProcObj, _1, _2, _3)); char cInPutBuf[256] = {0}; while ( true ) { printf("inPut cmd>: "); bzero(cInPutBuf, sizeof(cInPutBuf)); cin.getline(cInPutBuf,sizeof(cInPutBuf)); //读取一个命令 if (cInPutBuf[0] == 'q') { cout <<"Bye!"<<endl; break; } CDataProcess::getInstance()->processDataFunction(cInPutBuf, NULL, 0); //处理命令 } return 0; }
编译运行:
编辑
使用这个处理框架,可以优化程序处理结构,避免使用switch...case的冗长代码;
测试代码下载:http://download.csdn.net/download/wuquan_1230/10197636