• [转]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;  
    }  
    

      

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

  • 相关阅读:
    LintCode "Subarray Sum II"
    LintCode "Maximum Subarray Difference"
    LeetCode "Flip Game II"
    LintCode "Sliding Window Median" & "Data Stream Median"
    LintCode "Permutation Index"
    LintCode "Count of Smaller Number before itself"
    LeetCode "Nim Game"
    Etcd在Linux CentOS7下载、安装
    CentOS7 查看开启端口
    CentOS7-防火墙firewall 状态、重启、关闭
  • 原文地址:https://www.cnblogs.com/wlzy/p/8696372.html
Copyright © 2020-2023  润新知