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; }
三种方法的运行结果如下图所示: