/********************************************************************
* 文件名: CLK_LIB.h
* 文件描述: Switch_Case对象
* 创建人: 陈泽丹 ,2012年8月27日
* 版本号: 1.0
* 修改记录:
********************************************************************/
#include <iostream>
#include <tchar.h>
#include <windows.h>
using namespace std;
//时间守卫 - 用于测试经历时间
class Time_Guard
{
public:
Time_Guard(const char* _p_caption)
{
if( m_is_open)
{
size_t len = strlen(_p_caption);
if( len < MAX_PATH )
{
sprintf(m_caption,"%s", _p_caption);
}
else
{
sprintf(m_caption, "%s", "Error: caption is over stack! ");
cout<<"Error: "<<_p_caption<<"is over stack!"<<endl;
}
m_time = GetTickCount();
}
}
~Time_Guard()
{
if( m_is_open)
{
ULONG tm = GetTickCount() - m_time;
cout<<m_caption<<": "<<tm<<" (ms)"<<endl;
}
}
static void set_state(bool _is_open){ m_is_open = _is_open; }
private:
static bool m_is_open;
char m_caption[256];
ULONG m_time;
};
bool Time_Guard::m_is_open = true;
extern int count1 = 0;
extern int coutn2 = 0;
//Switch_Case对象
template< template< int v > class _PAR_TYPE, int _start, int _end>
class CLK_Switch
{
public:
template <class _PtrObj>
static bool switch_case(const _PtrObj& _p, const int _msg_type_ID, void* buf)
{
if( _msg_type_ID < _start || _msg_type_ID > _end || _start > _end)
return false;
const int POS = (_start + _end)/2;
if( POS == _msg_type_ID)
{
_PAR_TYPE< POS >* p_msg = ( _PAR_TYPE< POS >* ) buf;
_p->dispatch( p_msg );
return true;
}
else if( _msg_type_ID < POS )
{
count1++;
return CLK_Switch<_PAR_TYPE, _start, POS>::switch_case(_p, _msg_type_ID, buf);
}
else
{
count1++;
return CLK_Switch<_PAR_TYPE, POS+1, _end>::switch_case(_p, _msg_type_ID, buf);
}
}
};
template< class _Local_Type>
class CLK_Base_Case
{
public:
CLK_Base_Case(_Local_Type* _p_local):m_p_local(_p_local){}
virtual ~CLK_Base_Case(){ m_p_local = NULL; }
virtual void operator()(const int _msg_type_ID, void* buf) = 0;
protected:
_Local_Type* m_p_local;
};
/********************************************************************
* 文件名: Main.h
* 文件描述: Switch_Case对象
* 创建人: 陈泽丹 ,2012年8月27日
* 版本号: 1.0
* 修改记录:
********************************************************************/
#include <iostream>
#include <vector>
#include "CLK_LIB.h"
using namespace std;
template< int v >
class CLK_MSG
{
public:
enum { MSG_TYPE_ID = v };
};
class CLK_SERVER_MSG
{
public:
enum
{
MSG_START = 0,
MSG_END = 8,
};
class Action_Msg_Case: public CLK_Base_Case<CLK_SERVER_MSG>
{
public:
Action_Msg_Case(CLK_SERVER_MSG* _p):CLK_Base_Case<CLK_SERVER_MSG>(_p){}
virtual void operator()(const int _msg_type_ID, void* buf)
{
CLK_Switch<CLK_MSG, MSG_START, MSG_END>::switch_case(this, _msg_type_ID, buf);
}
template<class _T>
bool dispatch(_T* _msg)
{
//cout<<"通用操作!"<<endl;
count1++;
return true;
}
bool dispatch(CLK_MSG<1>* _msg)
{
//cout<<"my_dispatch!"<<endl;
count1++;
Sleep(2);
return true;
}
bool dispatch(CLK_MSG<2>* _msg)
{
//cout<<"my_dispatch!"<<endl;
count1++;
Sleep(2);
return true;
}
bool dispatch(CLK_MSG<3>* _msg)
{
//cout<<"my_dispatch!"<<endl;
count1++;
Sleep(2);
return true;
}
bool dispatch(CLK_MSG<4>* _msg)
{
//cout<<"my_dispatch!"<<endl;
count1++;
Sleep(2);
return true;
}
bool dispatch(CLK_MSG<5>* _msg)
{
//cout<<"my_dispatch!"<<endl;
count1++;
Sleep(2);
return true;
}
bool dispatch(CLK_MSG<6>* _msg)
{
//cout<<"my_dispatch!"<<endl;
count1++;
Sleep(2);
return true;
}
bool dispatch(CLK_MSG<7>* _msg)
{
//cout<<"my_dispatch!"<<endl;
count1++;
Sleep(2);
return true;
}
bool dispatch(CLK_MSG<8>* _msg)
{
//cout<<"my_dispatch!"<<endl;
count1++;
Sleep(2);
return true;
}
};
CLK_SERVER_MSG():action_msg_case(this){}
Action_Msg_Case action_msg_case;
virtual void on_action(const int _msg_type_ID, void* buf)
{
action_msg_case(_msg_type_ID, buf);
}
virtual void on_action1(const int _msg_type_ID, void* buf)
{
switch(_msg_type_ID)
{
case 1: coutn2++; Sleep(2); break;
case 2: coutn2++; Sleep(2); break;
case 3: coutn2++; Sleep(2); break;
case 4: coutn2++; Sleep(2); break;
case 5: coutn2++; Sleep(2); break;
case 6: coutn2++; Sleep(2); break;
case 7: coutn2++; Sleep(2); break;
case 8: coutn2++; Sleep(2); break;
default: coutn2++; break;
}
}
};
void Server()
{
Time_Guard tm_guard("Server msg");
CLK_SERVER_MSG msg;
for(int i=0; i<2000; i++)
msg.on_action(i%9, "123");
cout<<count1<<endl;
}
void Server1()
{
Time_Guard tm_guard("Server case");
CLK_SERVER_MSG msg;
for(int i=0; i<2000; i++)
msg.on_action1(i%9, "123");
cout<<coutn2<<endl;
}
void main()
{
Server();
Server1();
system("pause");
}
5557
Server msg: 5203 (ms)
2000
Server case: 5219 (ms)
请按任意键继续. . .
2000次调用case语句, 二分查找要试探5557次, 用系统的switch_case只要试探2000, 但二分查找的耗时和switch_case相差不下,甚至更快。 可见系统底层对switch_case很可能就是用o(n)遍历的算法的。