【问题标题】:c++ - other way of implementing function calls in switch casesc++ - 在switch case中实现函数调用的其他方式
【发布时间】:2014-06-02 22:38:58
【问题描述】:

我的代码如下:

void CashFlow::execute (int cmd)
{
    switch(cmd):
    {
        case BUY:
            BuyProc ();
            break;
        case SELL:
            SellProc ();
            break;
         ......
    }
}

我正在考虑做的可能是创建一个类似std::map <int, void (CashFlow::*)()> CashflowProcs; 的地图

然后也许使用 mCashFlowProcs = boost::assign::map_list_of (BUY, &CashFlow::BuyProc)(...etc)(..Etc.);

那我可以叫它(this->(mCashFlowProcs [cmd]))();

如何将其转换为模板以便重复使用?这个实现会不会有问题?

请注意,我没有使用 C++11

【问题讨论】:

  • boost::unordered_map<cmd_enum, boost::function<void()>>?
  • 虽然我可能只使用普通表。
  • 我不明白的是“如何将其变成模板以便可以重复使用”?你在这里问什么?您想在 CashflowProcs 类型上模板化这个概念吗?
  • @MooingDuck 这看起来是三个间接加上散列减去内联和潜在的缓存未命中 o.O
  • @dyp 好吧,这取决于数组或映射(或向量)是否是更/最优雅的方式,但映射会更具动态性。例如,如果 OP 想通过某种运行时机制(可能在将来)添加命令,则不能使用数组。而且我对这个问题思考得越多,我就越认为如果函数集或多或少是静态的,并且你只需在代码中列出它们一次,那么一个好的旧开关是最优雅的方式。但 OP 询问了替代方案。

标签: c++ templates boost stl


【解决方案1】:

这个实现会不会有问题?

是的,它很难维护,因为添加/删除命令需要大量维护,容易出错并且难以测试。因此,我建议在尝试改进此特定代码之前进行设计更改。

1 - 如果您可以更改设计:

使用class 表示命令

class Command
{
    public:
        virtual void Execute() = 0;
        virtual ~Command() {};;
};

class BuyCommand : public Command
{
    public:
        virtual void Execute() { cout << "BUY"; }
};

class SellCommand : public Command
{
    public:
        virtual void Execute() { cout << "SELL"; }
};

// ...
Command* bc = new BuyCommand();
// ...
bc->Execute();

2 - 如果(不幸地)你不能那样改变设计

如果cmd 枚举在编译时是已知的,并且大小有限,则可以使用boost::function 的数组,并且绝对应该在enum 中重新组合命令,而不是使用int .

enum { BUY = 0; SELL = 1; NB_CMDS= 2 };
...
boost::array<NB_CMDS, boost::function<void()>>  // N is the number of commands.

使用 cmd 索引您的数组,您只需调用该数组中索引为 cmd 的函数。

如果您在编译时不知道需要多少命令/函数,您可能需要将数组替换为 std::vector

如果有一天你可以使用 C++11,请将上述 sn-ps 中的 boost:: 替换为 std::

【讨论】:

  • 看起来改变设计是最好的。
猜你喜欢
  • 1970-01-01
  • 2021-02-20
  • 2021-04-02
  • 1970-01-01
  • 1970-01-01
  • 2017-06-16
  • 2016-11-25
  • 2011-08-30
  • 2013-09-13
相关资源
最近更新 更多