zoukankan      html  css  js  c++  java
  • C++ switch/case的替换方案

    switch语句改为多态结构更好些。

    1. 常规switch

    #include <iostream>
    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; 
    } 
    

    4.状态模式取代switch

    #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;
    }
    

    5. 多态+模板取代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
    ");
    	}
    };
     
    template <class S>
    void show( S shape)
    {
    	shape.showMessage();
    }
     
    int main()
    {
    	MessageOne shape1;
    	MessageTwo shape2;
    	MessageThree shape3;
    	show(shape1);
    	show(shape2);
    	show(shape3);
     
    	return 0;
    }
    

    参考: JoannaJuanCV

    作者:yusq77

    -------------------------------------------

    Wish you all the best and good health in 2021.

  • 相关阅读:
    2015年10月28日 json深切感受
    2015年10月27日 json数据小谈
    2015年10月26日 插件的使用
    2015/10/25 用bootstrap selectpicker实现带模糊查询的下拉列表
    2015年10月24号 哇,原来这JSP页面还可以用这东西!
    2015年10月23日 关于spring mvc的初认识
    2015年10月22日 杂感
    2015/10/21 http请求数据处理后显示
    2015/10/19总结:ajax传参、jquery.validate自定义日期校验
    记录一下----关于设计模式和面向对象设计原则
  • 原文地址:https://www.cnblogs.com/yusq77/p/13926475.html
Copyright © 2011-2022 走看看