/********************************************************************
file name : rc2bc.h
author : Clark/陈泽丹
created : 2011-12-21
备注:
由于模板的模板参数只能是类型或“编译期常量”,导致面对执行期变量模板的使用很麻烦。
本例通过二分查找,将“执行期变量”转成“编译期常量”。
补充:
本例属于静态分派,当命令类型超过1000后,编译时间在本人机器上达到十几秒。
以后的改善方法:通过宏命令和ID编码,对每个类定义一个自身的生成函数。
本解法的作用实例:
1,可以在网络通讯中省掉一大堆if/else或switch的转换语句。
2,可以让不同模块的人在添加模块时各自只局限性于自身的领域,
系统会通过偏特化机制自动把用户的模块添加进系统的功能里。
3,通过模板机制,让每个对象不用保持一致的基类,即每个做为接口的CMD类的功能和属性可以完全不同。
避免了采用虚函数时,要保持一致的接口再到子类里去实现的等绕来绕过问题。
*********************************************************************/
#include <iostream>
#include "ServerType.h"
using namespace std;
//--------------------- 框架类(服务端文件) -----------------------------
template<int v>
class CMD
{
public:
enum { value = v };
void run(){ cout<<"未定义指令: "<<value<<endl; }
};
//将执行期的变量转成编译期的常量(以便作为模板参数使用)
template<int s, int e>
class rc2bc
{
public:
static bool c2c(int i)
{
if( i<s || i>=e) return false;
const int POS = (s+e)/2;
CMD<POS> cmd;
if( cmd.value == i){ cmd.run(); return true; }
else if( cmd.value > i){ return rc2bc<s,POS>::c2c(i); }
else{ return rc2bc<POS,e>::c2c(i); }
}
};
template<int v>
class rc2bc<v, v>
{
public:
static bool c2c(int i){ return false; }
};
//--------------------------------------------------
//--------------------- 用户类1(客户端文件) -----------------------------
const int USER_CMD_1 = 1;
template<>
class CMD<USER_CMD_1>
{
public:
enum { value = USER_CMD_1 };
void run(){ cout<<"这是上线命令: "<<value<<endl; }
};
//--------------------- 用户类2(客户端文件) -----------------------------
const int USER_CMD_2 = 2;
template<>
class CMD<USER_CMD_2>
{
public:
enum { value = USER_CMD_2 };
void run(){ cout<<"这是掉线命令: "<<value<<endl; }
};
//执行
void main()
{
for(int CMD_ID=-5; CMD_ID<5; CMD_ID++)
rc2bc<1, 100>::c2c(CMD_ID);
system("pause");
}