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

  

三種方法的運行結果如下圖所示:


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM