【问题标题】:avoiding if statements on a static boolean for logic decision making避免使用静态布尔值进行逻辑决策的 if 语句
【发布时间】:2016-03-31 02:00:51
【问题描述】:

我有一个类,它的成员 itemType 只设置一次并且从不修改,但它在许多 if 语句中用于决定调用哪个函数。 由于 itemType 仅设置一次,因此可以避免在类中的 else 位置使用 if 语句。这将简化和清理代码,另外还可以节省 if 检查的开销。 我在考虑函数一个指针,我可以根据 itemType 值在构造函数中初始化。 有没有其他更好的方法可以做到这一点?

请注意原始类和代码库很大,我不能根据 itemtype 创建子类。

enum ItemTypes
{
    ItemTypeA,
    ItemTypeB,
};


class ItemProcessing
{
public:

    //This function is called hundreds of times
    void ProcessOrder(Order* order)
    {
        //This member itemType is set only once in the constructor and never modified again
        //Is there a way to not check it all the time??
        if (itemtype == ItemTypes::ItemTypeA )
        {
            ProcessTypeA(order)
        }
        else if (itemtype == ItemTypes::ItemTypeB )
        {
            ProcessTypeB(order)
        }
    }

    ItemProcessing(ItemTypes itype)
    {
        itemtype = itype; //can  I do something here like setting a function pointer so I dont have to check this property in ProcessOrder() and call the relevant function directly.
    }

private:

    ItemTypes itemtype;
    void ProcessTypeA(Order*);
    void ProcessTypeB(Order*);
};

【问题讨论】:

  • 你考虑过函数指针吗?

标签: c++ logic


【解决方案1】:

使用由itemtype 索引的函数指针数组,如下所示:

typedef void(*ProcessType_func_t)(Order *);

ProcessType_func_t processType_f[] = {
    ProcessTypeA,
    ProcessTypeB
};

那么你可以这样做:

void ProcessOrder(Order *order) {
    ProcessType_f[itemtype](order);
}

如果你有很多不同的函数需要像这样调度,你可以使用结构。

struct {
    ProcessType_func_t processType_f,
    OtherType_func_t otherType_f,
    ...
} dispatchTable[] = {
    { ProcessTypeA, OtherTypeA, ... },
    { ProcessTypeB, OtherTypeB, ... }
};

然后你会使用它:

dispatchTable[itemtype].processType_f(order);

最后,您可以通过定义新类来实现完全面向对象的方法:

class Processor { // abstract base class
    public:
        virtual void Process(Order *order) = 0;
};

class ProcessorA {
    public: 
        void Process(Order *order) {
            ProcessTypeA(order);
        }
}


class ProcessorB {
    public: 
        void Process(Order *order) {
            ProcessTypeB(order);
        }
}

那么你可以有一个成员变量

Processor *processor;

当你设置itemtype时初始化它

ItemProcessing(ItemTypes itype)
{
    itemtype = itype;
    if (itemtype == ItemTypeA) {
        processor = new ProcessorA;
    } else {
        processor = new ProcessorB;
    }
}

然后你会使用它:

processor->Process(order);

这很容易扩展以支持更多需要在 itemtype 上调度的函数——它们都成为类中的方法。

我希望我的语法是正确的,实际上我自己并没有做太多的 C++ OO 编程。

【讨论】:

  • 这就是我最初想做的事情,正如我在原始帖子中提到的那样。我只是想知道是否还有其他更好的方法。
  • 我添加了一个面向对象的方法
【解决方案2】:

您可以考虑使用两个指向成员方法的指针状态模式
前一种解决方案可能具有更高的性能,而后者更加优雅和灵活(至少从我的角度来看)。

有关状态模式的更多详细信息,请参阅here。这种模式非常适合您的问题,即使您必须重构一些类。
我想第一个建议确实很清楚,不需要进一步的细节。

【讨论】:

    【解决方案3】:

    在 c++ 中,指向函数的指针应该与虚函数和继承相仿。 (多态性) 定义一个包含纯虚方法的虚类 processOrder ( Order* ordre); 并为枚举的每个值定义子类。 您可以使用抽象工厂模式来创建这些对象,或者如果需要的话。

    如果愿意,我可以编写代码。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-09-30
      • 2014-09-02
      • 2018-08-10
      • 2016-11-20
      • 2018-04-17
      • 2012-02-09
      • 1970-01-01
      相关资源
      最近更新 更多