在消息处理的时候,一般都用switch(msgid) case的方式来处理不同消息,但是随着消息的增多,就显得不方便;
解决方法:利用回调函数,来定制查找表
http://blog.youkuaiyun.com/hjsunj/article/details/2037354
//查找表
MsgFunc dataManager::LookUp(int msgID)
{
//声明表结构
typedef map<int, MsgFunc> Registry;
struct RegistryInitializer
{
const Registry& operator()()
{
//定义表
static Registry registry;
registry[OPP_CTN_APPINSTANCES_REQUEST] = &dataManager::appInstances;//应用实例
return registry;
}
};
//find
static const Registry& registry = RegistryInitializer()();
Registry::const_iterator it = registry.find(msgID);
if(it != registry.end())
{
return it->second;
}
else
{
//unknown msgid
return NULL;
}
}
//外部调用
MsgFunc msgFunc = LookUp(msgID);
if(msgFunc != NULL)
{
string coremsg = (this->*msgFunc)(baseMsg, cxt);
if(coremsg != "")
return coremsg;
}
else
{
//unknow msgid
}
2,用模板类来实现查找表
///h
#ifndef __I_REG_BASE_H__
#define __I_REG_BASE_H__
#if defined(_MSC_VER) && 1020 <= _MSC_VER
#pragma once
#endif
#include <map>
#include <algorithm>
using namespace std;
#include "IRegExcept.h"
template< class Key, class Cls, class Retn = void, class Compare = less<Key> >
class IBindDispatch0
{
public :
typedef Retn (Cls::*Fun)(void);
typedef CBindException<Key> ExcepCls;
void Bind( const Key& key, Fun bindItem );
Retn Invok( const Key& key, Cls& clsApp );
private :
std::map< Key, Fun, Compare > m_mpBindContainer;
};
template< class Key, class Cls, class Param1, class Retn = void, class Compare = less<Key> >
class IBindDispatch1
{
public :
typedef Retn (Cls::*Fun)(Param1);
typedef CBindException<Key> ExcepCls;
void Bind( const Key& key, Fun bindItem );
Retn Invok( const Key& key, Cls& clsApp, Param1 arg1 );
private :
std::map< Key, Fun, Compare > m_mpBindContainer;
};
template< class Key, class Cls, class Param1, class Param2, class Retn = void, class Compare = less<Key> >
class IBindDispatch2
{
public :
typedef Retn (Cls::*Fun)(Param1,Param2);
typedef CBindException<Key> ExcepCls;
void Bind( const Key& key, Fun bindItem );
Retn Invok( const Key& key, Cls& clsApp, Param1 arg1, Param2 arg2 );
private :
std::map< Key, Fun, Compare > m_mpBindContainer;
};
template< class Key, class Cls, class Param1, class Param2, class Param3, class Retn = void, class Compare = less<Key> >
class IBindDispatch3
{
public :
typedef Retn (Cls::*Fun)(Param1,Param2,Param3);
typedef CBindException<Key> ExcepCls;
void Bind( const Key& key, Fun bindItem );
Retn Invok( const Key& key, Cls& clsApp, Param1 arg1, Param2 arg2, Param3 arg3);
private :
std::map< Key, Fun, Compare > m_mpBindContainer;
};
#include "IRegCplusplus.inl"
#endif
cpp
template< class Key, class Cls, class Retn, class Compare >
void IBindDispatch0< Key, Cls, Retn, Compare >::Bind( const Key& key, Fun bindItem )
{
if ( NULL != bindItem ) {
m_mpBindContainer[key] = bindItem;
}
}
template< class Key, class Cls, class Retn, class Compare >
Retn IBindDispatch0< Key, Cls, Retn, Compare >::Invok( const Key& key, Cls& clsApp )
{
std::map< Key, Fun, Compare >::iterator it = m_mpBindContainer.find(key);
if ( it == m_mpBindContainer.end() )
{
throw ExcepCls(key, "Can't Find Key!");
return Retn(0);
}
return (clsApp.*(it->second))();
}
//
template< class Key, class Cls, class Param1, class Retn, class Compare >
void IBindDispatch1< Key, Cls, Param1, Retn, Compare >::Bind( const Key& key, Fun bindItem )
{
if ( NULL != bindItem ) {
m_mpBindContainer[key] = bindItem;
}
}
template< class Key, class Cls, class Param1, class Retn, class Compare >
Retn IBindDispatch1< Key, Cls, Param1, Retn, Compare >::Invok( const Key& key, Cls& clsApp, Param1 arg1 )
{
std::map< Key, Fun, Compare >::iterator it = m_mpBindContainer.find(key);
if ( it == m_mpBindContainer.end() )
{
throw ExcepCls(key, "Can't Find Key!");
return Retn(0);
}
return (clsApp.*(it->second))(arg1);
}
//
template< class Key, class Cls, class Param1, class Param2, class Retn, class Compare >
void IBindDispatch2< Key, Cls, Param1, Param2, Retn, Compare >::Bind( const Key& key, Fun bindItem )
{
if ( NULL != bindItem ) {
m_mpBindContainer[key] = bindItem;
}
}
template< class Key, class Cls, class Param1, class Param2, class Retn, class Compare >
Retn IBindDispatch2< Key, Cls, Param1, Param2, Retn, Compare >::Invok( const Key& key, Cls& clsApp, Param1 arg1, Param2 arg2 )
{
std::map< Key, Fun, Compare >::iterator it = m_mpBindContainer.find(key);
if ( it == m_mpBindContainer.end() )
{
throw ExcepCls(key, "Can't Find Key!");
return Retn(0);
}
return (clsApp.*(it->second))(arg1,arg2);
}
//
template< class Key, class Cls, class Param1, class Param2, class Param3, class Retn, class Compare >
void IBindDispatch3< Key, Cls, Param1, Param2, Param3, Retn, Compare >::Bind( const Key& key, Fun bindItem )
{
if ( NULL != bindItem ) {
m_mpBindContainer[key] = bindItem;
}
}
template< class Key, class Cls, class Param1, class Param2, class Param3, class Retn, class Compare >
Retn IBindDispatch3< Key, Cls, Param1, Param2, Param3, Retn, Compare >::Invok( const Key& key, Cls& clsApp, Param1 arg1, Param2 arg2, Param3 arg3 )
{
std::map< Key, Fun, Compare >::iterator it = m_mpBindContainer.find(key);
if ( it == m_mpBindContainer.end() )
{
throw ExcepCls(key, "Can't Find Key!");
return Retn(0);
}
return (clsApp.*(it->second))(arg1,arg2,arg3);
}
//
//exception.h
#ifndef __I_REG_EXCEPTION_H__
#define __I_REG_EXCEPTION_H__
template< class Key >
class CBindException
{
CBindException() : m_pError(NULL) {}
public :
CBindException(const Key& keyVal, const char* pErrorDescrip = NULL )
:m_stKeyVal(keyVal)
,m_pError(pErrorDescrip)
{
}
Key GetKeyVal( void )
{
return m_stKeyVal;
}
const char* GetErrorDescrip( void ) { return m_pError; }
private :
Key m_stKeyVal;
const char* m_pError;
};
#endif