首先上代码:
cpp
#include <iostream>
#include <memory>
class Context;
class State {
public:
virtual void Handle(Context * context) = 0; //纯虚函数
virtual ~State() = default; //虚析构函数
};
//创建状态A
class ConcreateStateA : public State{
public:
virtual void Handle(Context* context);
};
//创建状态B
class ConcreateStateB : public State {
public:
virtual void Handle(Context* context);
};
//上下文类
class Context {
public:
Context(std::shared_ptr<State> state) :m_state(state) {};
//请求操作
void request() {
if (m_state) {
m_state->Handle(this); //使用委托,调用具体状态
}
}
//改变状态
void changeState(std::shared_ptr<State> state) {
this->m_state = state;
}
//展示当前ID
void showID() {
std::cout << "当前ID是 " << id << std::endl;
}
private:
std::shared_ptr<State> m_state;
int id = 10;
};
int main() {
std::shared_ptr<State> stateA = std::make_shared<ConcreateStateA>(); //状态A
std::shared_ptr<State> stateB = std::make_shared<ConcreateStateB>(); //状态B
//创建上下文并设置状态
std::shared_ptr<Context> m_context = std::make_shared<Context>(stateA); //创建上下文
m_context->request();
//切换状态
m_context->changeState(stateB); //切换状态B
m_context->request();
return 0;
}
inline void ConcreateStateA::Handle(Context* context) {
std::cout << "当前是状态A" << std::endl;
context->showID();
}
inline void ConcreateStateB::Handle(Context* context) {
std::cout << "当前是状态B" << std::endl;
context->showID();
}
然后是UML图:
context 中使用委托将自身传递给state,然后根据状态的不同,调用不同的状态对象,然后执行后面的状态。
因为context中的change函数中留的是接口函数state,所以如果要添加新的状态,可以直接添加一个CpncreateStateC状态,然后执行这个状态的中相应的操作。同时因为前面已经使用委托将context自身传递给了State的派生类,所以只要留好公有方法就可以很方便的访问原本的数据。
最后还有一点,在使用委托的时候,因为是传递this指针,所以就不需要再handle()函数接口中传递智能指针形式了。
此文乃录状态模式之学,并附己之心得,以备后日查阅。原文链接如下。
C++设计模式------状态模式 - Ring_1992 - 博客园