考虑来自某个地方的数据包。它有字段VERSION,有N个可能的输入数据包版本。 对于从X到1的每个数据包VERSION,每个包含VERSION X的数据包都必须通过适当的方法/指令集进行处理。完成此任务的唯一想法非常难看:
PACKET p = GetPacketFromSomewhere();
// p.VERSION is 3
if (p.VERSION > 0) {
// things for p.VERSION == 1
}
if (p.VERSION > 1) {
// things for p.VERSION == 2
}
if (p.VERSION > 2) {
// things for p.VERSION == 3
}
// set of if statements up to version N
真实的情况是,我的数据包VERSIONS高于10,事情仍有可能改变。当我需要保持向后兼容性时,将添加新的数据包VERSIONS。这段代码很糟糕,至少我不喜欢它。你们有更好的想法如何处理这种情况吗?
答案 0 :(得分:2)
使用map
类型map<unsigned int, function>
,其中function
是指向所需类型函数的指针:
typedef void (*function)();
std::map<int,function> handlers;
handlers[1] = &ver1handler;
...
handlers[N] = &verNhandler;
if(handlers.count(p.VERSION))
(*handlers.find(p.VERSION))();
其中ver[N+1]handler
定义为:
void ver[N+1]handler(){
ver[N]handler();
// additional handle commands
}
或者使用switch
命令,并以相同的方式定义处理程序。
答案 1 :(得分:2)
如果处理顺序不重要,您可以使用不间断的开关:
PACKET p = GetPacketFromSomewhere();
// p.VERSION is 3
switch (p.VERSION) {
case 3: {
// things for p.VERSION == 3
}
case 2: {
// things for p.VERSION == 2
}
case 1: {
// things for p.VERSION == 1
}
}
编辑: 您还可以使用递归函数模板特化:
template<int N>
void proc(PACKET& p){
proc<N-1>(p);
}
template<>
void proc<1>(PACKET& p){
//things for p.VERSION == 1
}
template<>
void proc<2>(PACKET& p){
proc<1>(p)
//things for p.VERSION == 2
}
template<>
void proc<3>(PACKET& p){
proc<2>(p)
//things for p.VERSION == 3
}
然后调用这样的处理函数:
switch (p.VERSION ) {
case 1: proc<1>(p) break;
case 3: proc<2>(p) break;
case 3: proc<3>(p) break;
default: {
std::cout << "Protocol version not impplemented - using highest known version" << std::endl;
proc<3>(p);
}
这也应该是非常有效的性能(如果这是您的担忧),并且您不必担心协议版本中的差距。