C ++多条件语句 - 合并

时间:2011-09-13 06:42:22

标签: c++

我根据规范编写了一个程序 规范有大约3种类型,每种类型在每一个点上都有不同的处理方式。

这或多或少意味着代码可读性,我写的如下所示,现在我的问题是,如果你有 200 这样的语句,那不是吗值得将它们合并为一个“if enum-type x”

我相信有一个程序已经在那里做了但是谷歌对这个具体问题没有多大帮助。提前感谢您的帮助。

/* Point 1.15 Filling Customers bdate */

if(current.identifier == APPLE){ output.setValue(1.15, additionalObj.some.color)}
if(current.identifier == PLUM){ output.setValue(1.15, otherObj.another.color) }
if(current.identifier == GRAPE){ output.setValue(1.15, default::color) }


/* Point 1.16 Filling Customers cash*/

if(current.identifier == APPLE){ do whatever}
if(current.identifier == PLUM){ do whatever}
if(current.identifier == GRAPE){ do whatever}

要实现的目标:

if(current.identifier == APPLE){ output.setValue(1.15, additionalObj.some.color) 
                                 do whatever
}

依此类推,所以我可以自动将它们合并为1个语句,而我仍然拥有可读代码

编辑:我可能误导了你,它实际上不是一个类型,它只是一个带有字符串标识符和SubObjects的对象,所以我不能使用多态。我已经调整了以上内容,你可以看到我想要实现的目标。

4 个答案:

答案 0 :(得分:5)

如果您还没有理解它们,请阅读C ++类继承和多态。 C ++的这两个功能将提供一种更优雅的方式来解决您的问题。

答案 1 :(得分:3)

基本多态方法:

enum Type { tX, tY, tZ};

struct Data
{
    Type type;
    int data_;
};

class Processor
{

public:

    virtual void fillCustomersBDate(const Data& data) = 0; 
    virtual void fillCustomersCash(const Data& data) = 0;

};

class XProcessor : public Processor 
{
    virtual void fillCustomersBDate(const Data& data) { /* X stuff */}
    virtual void fillCustomersCash(const Data& data) {/* X stuff */}
};
class YProcessor : public Processor 
{
    virtual void fillCustomersBDate(const Data& data) {/* Y stuff */}
    virtual void fillCustomersCash(const Data& data) {/* Y stuff */}
};

void process(const Data& data)
{
    Processor* processor = processorForType(data.type);
    // Do general stuff
    processor->fillCustomersBDate(data);
    // Do general stuff
    processor->fillCustomersCash(data);
    // Do general stuff
    delete processor;
}

更有可能的是,您将大部分主要流程移动到基类中。

答案 2 :(得分:1)

我有两种方法可以做到这一点:第一种是多态行为(通过虚函数或类型参数化);第二个是switch类型。

对于第一个类型,每个类型都可以从一个公共(可能是抽象的)基类继承:

class Base
{
public:

    virtual void DoSomething( ) =0;

};

class A : public Base
{
public:
    void DoSomething( )
    {
        cout << "I'm doing something from A!" << endl;
    }
};

class B : public Base
{
public:
    void DoSomething( )
    {
        cout << "I'm doing something from B!" << endl;
    }
};

这样,您只需使用Base &Base *类型的变量或Base的任何智能指针(例如shared_ptr<Base),并调用{{ 1}}该变量的方法。将根据变量的运行时类型调用DoSomething的正确实现(因为DoSomething是虚方法)。

实现类似行为的另一种方法是通过模板。它的使用方式与第一个建议类似,但您不需要基类,并且方法不必是虚拟的:

DoSomething

然后处理操作的函数可以这样定义:

class A
{
public:
    void DoSomething( )
    {
        cout << "I'm doing something from A!" << endl;
    }
};

class B
{
public:
    void DoSomething( )
    {
        cout << "I'm doing something from B!" << endl;
    }
};

并像这样使用:

template<typename T>
void PolymorphicDoSomething( T variable )
{
    T.DoSomething( );
}

当然,这个例子有点人为,但这是基本的想法,根据具体情况可能非常有用。

另一种可能性是基本上做你现在正在做的事情,但只有一个A a; PolymorphicDoSomething( a ); 语句,而不是几个switch语句。如果变量的类型存储为ifenum,则可以使用开关有效地确定要执行的操作:

int

但我怀疑这比使用虚拟方法更有效。此外,虚拟方法更易于管理 - 为了扩展功能,您必须简单地声明另一个类,并且您已经拥有的所有代码都能够应对它。在交换机的情况下,您必须在检查变量类型的任何地方添加一个case语句。所以在这种情况下我真的会坚持使用虚拟方法。

答案 3 :(得分:0)

如果它们完全不同,您可以将它们分成以下各个部分:

if (type x)
    processX1v1_thru_1v15(); // will do all steps 1.1 thru 1.16 for type x
else if (type y)
    processY1v1_thru_1v15(); // will do all steps 1.1 thru 1.16 for type y
: : :
and so on.

但是你可能想要研究多态性,这将允许你为每个类/类型指定不同的“任何”。你可以像以下一样做:

obj.doWhatever1_01();  // calls obj-specific method depending on type.
obj.doWhatever1_02();
: : :
obj.doWhatever1_16();