[转]C++ 取代switch的三种方法

 1.常规switch

enum EnumType  
{  
    enumOne,  
    enumTwo,  
    enumThree  
};  
  
void showMessage(int type)  
{  
    switch(type)  
    {  
    case enumOne:  
        printf("This is message one\n");  
        break;  
    case enumTwo:  
        printf("This is message two\n");  
        break;  
    case enumThree:  
        printf("This is message three\n");  
        break;  
    default:  
        printf("This is wrong message\n");  
        break;  
    }  
}  
  
int main()  
{  
//常规switch  
    showMessage(enumOne);  
    showMessage(enumTwo);  
    showMessage(enumThree);  
  
    return 0;  
}  

 

2.多态+std::map取代switch

#include <map>  
  
enum EnumType  
{  
    enumOne,  
    enumTwo,  
    enumThree  
};  
  
class Base  
{  
public:  
    Base(){}  
    virtual ~Base(){}  
    virtual void showMessage(){}  
};  
  
class MessageOne:public Base  
{  
public:  
    MessageOne(){}  
    ~MessageOne(){}  
    void showMessage()  
    {  
        printf("This is message one\n");  
    }  
};  
  
class MessageTwo:public Base  
{  
public:  
    MessageTwo(){}  
    ~MessageTwo(){}  
    void showMessage()  
    {  
        printf("This is message two\n");  
    }  
};  
  
class MessageThree:public Base  
{  
public:  
    MessageThree(){}  
    ~MessageThree(){}  
    void showMessage()  
    {  
        printf("This is message three\n");  
    }  
};  
  
int main()  
{  
//多态+std::map取代switch  
    std::map<int,Base*> baseMap;  
    baseMap.insert(std::make_pair(enumOne,new MessageOne));  
    baseMap.insert(std::make_pair(enumTwo,new MessageTwo));  
    baseMap.insert(std::make_pair(enumThree,new MessageThree));  
    baseMap[enumOne]->showMessage();  
    baseMap[enumTwo]->showMessage();  
    baseMap[enumThree]->showMessage();  
  
    return 0;  
}  

  上述完全是一个面向过程到面向对象的转变:将每个case分支都作为一个子对象,然后用C++语言的多态性去动态绑定。这样做确实是带来了性能上的损失,但是在当今的CPU计算能力而言,这是可以忽略的,而它带来的好处却很有用:
(1)分支的增减只要继续派生即可;
(2)子类代表了一个case,比必须用type去硬编码的case语句更加具有可读性;
(3)代码的可读性增强,使得分支的维护性增加;
(4)面向对象的思想更加符合人看世界的方式;

(5)避免了漏写break语句造成的隐蔽错误。

 

3.函数指针+std::map取代switch

#include <map>  
  
enum EnumType  
{  
    enumOne,  
    enumTwo,  
    enumThree  
};  
  
void showMessageOne()  
{  
    printf("This is message one\n");  
}  
  
void showMessageTwo()  
{  
    printf("This is message two\n");  
}  
  
void showMessageThree()  
{  
    printf("This is message three\n");  
}  
  
int main()  
{  
//函数指针+std::map取代switch  
    typedef void (*func)();  
  
    std::map<int,func> funcMap;  
    funcMap.insert(std::make_pair(enumOne,showMessageOne));  
    funcMap.insert(std::make_pair(enumTwo,showMessageTwo));  
    funcMap.insert(std::make_pair(enumThree,showMessageThree));  
    funcMap[enumOne]();  
    funcMap[enumTwo]();  
    funcMap[enumThree]();  
  
    return 0;  
}  

  

值得注意的是函数指针要用typedef定义,否则报错。

 

4.状态模式取代switch

关于设计模式中的状态模式可参考:C++设计模式——状态模式

直接上代码。

#include <stdio.h>  
class Context;  
class State  
{  
public:  
    State(){}  
    virtual ~State (){}  
    virtual void showMessage(Context *pContext)=0;  
};  
  
class MessageOne:public State  
{  
public:  
    MessageOne(){}  
    ~MessageOne(){}  
    void showMessage(Context *pContext)  
    {  
        printf("This is message one\n");  
    }  
};  
  
class MessageTwo:public State  
{  
public:  
    MessageTwo(){}  
    ~MessageTwo(){}  
    void showMessage(Context *pContext)  
    {  
        printf("This is message two\n");  
    }  
};  
  
class MessageThree:public State  
{  
public:  
    MessageThree(){}  
    ~MessageThree(){}  
    void showMessage(Context *pContext)  
    {  
        printf("This is message three\n");  
    }  
};  
  
class Context  
{  
public:  
     Context(State *pState) : m_pState(pState){}  
  
     void Request()  
     {  
          if (m_pState)  
          {  
               m_pState->showMessage(this);  
          }  
     }  
  
     void ChangeState(State *pState)  
     {  
          m_pState = pState;  
     }  
  
private:  
     State *m_pState;  
};  
  
int main()  
{  
     State *pStateA = new MessageOne();  
     State *pStateB = new MessageTwo();  
     State *pStateC = new MessageThree();  
     Context *pContext = new Context(pStateA);  
     pContext->Request();  
  
     pContext->ChangeState(pStateB);  
     pContext->Request();  
  
     pContext->ChangeState(pStateC);  
     pContext->Request();  
  
     delete pContext;  
     delete pStateC;  
     delete pStateB;  
     delete pStateA;  
  
     return 0;  
}  

  

三种方法的运行结果如下图所示:

posted @ 2018-04-02 19:07  ZYVV  阅读(4276)  评论(0编辑  收藏  举报