21、状态模式(行为性模式)

时间:2024-03-08 09:47:41

版本一、get状态指针

#include <iostream>
using namespace std;

//前置声明
class Context;

//状态
class State{
public:
	//4个状态
    virtual void toUp   (Context& context){ }
    virtual void toDown (Context& context){ }
    virtual void toLeft (Context& context){ }
    virtual void toRight(Context& context){ }
	//显示用
    virtual void print(){}  
};    

//Context
class Context{
public:
    Context(State *st ):st(st){ }
    void reset( State* st ){     
        this->st = st;
    }
    State* get(){  //获取私有状态指针
        return st;
    }
    ~Context(){ delete st; }
private:
    State* st;
};

//具体状态Up
class Up :public State {
public:
    virtual void print(){
        cout << "now Up\n";
    }
    virtual void toDown(Context& context);
};

//具体状态Down
class Down:public State {
public:
    virtual void print(){
        cout << "now Down\n";
    }
    virtual void toUp(Context& context);
};

//
void Up::toDown(Context& context) {
    context.~Context();
    context.reset( new Down );    
}
void Down::toUp(Context& context) {
    context.~Context();
    context.reset(new Up );    
}

int main() 
{
	Context c(new Up);     //定义对象
	( c.get() )->print();  //当前状态

	( c.get() )->toDown(c); // c 转换状态
	( c.get() )->print();    //转换过的状态
	
    return 0;
}

版本二、统一接口

#include <iostream>

//前置声明
class Context;

//状态
class State{
public:
	//4个状态
    virtual void toUp   (Context& context){ }
    virtual void toDown (Context& context){ }
    virtual void toLeft (Context& context){ }
    virtual void toRight(Context& context){ }
	//显示用
    virtual void print(){}  
};    

//Context
class Context{
public:
    Context(State *st ):st(st){ }
    void reset( State* st ){     
        this->st = st;
    }
	//统一接口
    void toUp   (){ st->toUp(*this); }
    void toDown (){ st->toDown(*this); }
    void toLeft (){ st->toLeft(*this); }
    void toRight(){ st->toRight(*this); }
	void print  (){st->print(); }
    ~Context(){ delete st; }
private:
    State* st;
};

//具体状态Up
class Up :public State {
public:
    virtual void print(){
        std:: cout << "now Up\n";
    }
    virtual void toDown(Context& context);
};

//具体状态Down
class Down:public State {
public:
    virtual void print(){
        std:: cout << "now Down\n";
    }
    virtual void toUp(Context& context);
};

//类外定义
void Up::toDown(Context& context) {
    context.~Context();
    context.reset( new Down );    
}
void Down::toUp(Context& context) {
    context.~Context();
    context.reset(new Up );    
}

int main() 
{
	Context c(new Up);     //定义对象
	c.print();  //当前状态

	c.toDown(); // 转换状态
	c.print();  //转换过的状态
	
    return 0;
}

版本三、成员函数指针数组

#include <iostream>

//前置声明
class Context;

//状态
class State{
public:
	//4个状态
    virtual void toUp   (Context& context){ }
    virtual void toDown (Context& context){ }
    virtual void toLeft (Context& context){ }
    virtual void toRight(Context& context){ }
	//成员函数指针数组
	enum Direction { TOUP,TODOWN,TOLEFT,TORIGHT };
	typedef void (State::*Action)(Context& context); //Action是可以指向,任何表示方向的成员函数指针
    static Action Menu[]; //成员函数指针数组
	//显示用
    virtual void print(){}  
}; 
//成员函数指针数组初始化   
State::Action Menu[] = { &State::toUp,&State::toDown,&State::toLeft,&State::toRight };  

//Context
class Context{
public:
    Context(State *st ):st(st){ }
    void reset( State* st ){     
        this->st = st;
    }
	//转换状态
    void conversionState( State::Direction d ){
		(st->*Menu[d])(*this);
	}
	void print  (){st->print(); }
    ~Context(){ delete st; }
private:
	
    State* st;
};

//具体状态Up
class Up :public State {
public:
    virtual void print(){
        std:: cout << "now Up\n";
    }
    virtual void toDown(Context& context);
};

//具体状态Down
class Down:public State {
public:
    virtual void print(){
        std:: cout << "now Down\n";
    }
    virtual void toUp(Context& context);
};

//类外定义
void Up::toDown(Context& context) {
    context.~Context();
    context.reset( new Down );    
}
void Down::toUp(Context& context) {
    context.~Context();
    context.reset(new Up );    
}

int main() 
{
	Context c(new Up);     //定义对象
	c.print();  //当前状态

	c.conversionState( State::TODOWN ); // 转换状态
	c.print();  //转换过的状态
	
    return 0;
}