如何根据一对枚举的值选择一个动作?

时间:2013-04-14 07:13:50

标签: c++ software-design

我在C ++中实现协议模型(特别是缓存一致性协议,但这个问题无关紧要)

协议采用两个值:previous_statemessage_type。两者都是枚举。协议应为两个输入的每个组合选择一个唯一的动作。某些组合无效(应显示错误),并且会停止一些组合。

用C ++编写上述场景的好方法是什么?我可以想到:两个嵌套的开关块用于选择输入组合,并调用作为函数实现的特定操作。

是否有更优雅灵活的方式来编写上述方案?理想情况下,从协议中添加/删除输入组合应该很容易。

感谢您的任何建议。 (我是设计模式的新手,并且不知道任何适合的模式)

2 个答案:

答案 0 :(得分:1)

假设两个枚举是32位值。我会做这样的事情:

void doit(E1 previous_state, E2 message_type) {
# define COMBINE(_x_, _y_) (static_cast<int64_t>(previous_state) << 32 | message_type)
  switch (COMBINE(previous_state, message_type) {
  case COMBINE(e1value1, e2value1):
    // ...
    break;
  case COMBINE(e1value4, e2value3):
    // ...
    break;
  // ... more cases ...
  default:
    // report error
  }
}

不要认为这会产生更快的代码 - switch语句通常被优化为跳转表,但是这样的技巧可能会失败。如果你最感兴趣的是最好的性能,你将不得不尝试并找出哪个系统最好(注意将int64_t更改为更小的类型并最小化我的示例中的移位可能会产生一些影响)。

答案 1 :(得分:1)

为什么不使用简单的二维数组?例如

enum Previous_state
{
state_1 = 0,
state_2,
...,
state_n,
PreviousLastValue
}

enum Message_type
{
type_1 = 0,
type_2,
...,
type_n,
TypeLastValue
}
...

Action actions[PreviousLastValue][TypeLastValue] = {NULL}; 

void SetAction(Previous_state state, Message_type type, Action action)
{
    actions[state][type] = action;
}

void RemoveAction(Previous_state state, Message_type type)
{
    actions[state][type] = 0;
}

void GetAction(Previous_state state, Message_type type)
{
    if(actions[state][type] == 0)
    {
        //display error
    }

    return actions[state][type];
}