zoukankan      html  css  js  c++  java
  • [转]C++ 取代switch的三种方法

     1.常规switch

    enum EnumType  
    {  
        enumOne,  
        enumTwo,  
        enumThree  
    };  
      
    void showMessage(int type)  
    {  
        switch(type)  
        {  
        case enumOne:  
            printf("This is message one
    ");  
            break;  
        case enumTwo:  
            printf("This is message two
    ");  
            break;  
        case enumThree:  
            printf("This is message three
    ");  
            break;  
        default:  
            printf("This is wrong message
    ");  
            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
    ");  
        }  
    };  
      
    class MessageTwo:public Base  
    {  
    public:  
        MessageTwo(){}  
        ~MessageTwo(){}  
        void showMessage()  
        {  
            printf("This is message two
    ");  
        }  
    };  
      
    class MessageThree:public Base  
    {  
    public:  
        MessageThree(){}  
        ~MessageThree(){}  
        void showMessage()  
        {  
            printf("This is message three
    ");  
        }  
    };  
      
    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
    ");  
    }  
      
    void showMessageTwo()  
    {  
        printf("This is message two
    ");  
    }  
      
    void showMessageThree()  
    {  
        printf("This is message three
    ");  
    }  
      
    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
    ");  
        }  
    };  
      
    class MessageTwo:public State  
    {  
    public:  
        MessageTwo(){}  
        ~MessageTwo(){}  
        void showMessage(Context *pContext)  
        {  
            printf("This is message two
    ");  
        }  
    };  
      
    class MessageThree:public State  
    {  
    public:  
        MessageThree(){}  
        ~MessageThree(){}  
        void showMessage(Context *pContext)  
        {  
            printf("This is message three
    ");  
        }  
    };  
      
    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;  
    }  
    

      

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

  • 相关阅读:
    28完全背包+扩展欧几里得(包子凑数)
    HDU 3527 SPY
    POJ 3615 Cow Hurdles
    POJ 3620 Avoid The Lakes
    POJ 3036 Honeycomb Walk
    HDU 2352 Verdis Quo
    HDU 2368 Alfredo's Pizza Restaurant
    HDU 2700 Parity
    HDU 3763 CDs
    POJ 3279 Fliptile
  • 原文地址:https://www.cnblogs.com/wlzy/p/8696372.html
Copyright © 2011-2022 走看看