状态模式通过封装不同状态的行为并实现状态间切换,使对象在运行时改变行为。它由Context、State和ConcreteState三部分组成,避免了冗长的条件判断,提升了代码可维护性与扩展性,适用于状态多且转换复杂的场景。

状态模式(State Pattern)是C++中常用的行为型设计模式之一,它允许对象在内部状态改变时改变其行为,仿佛改变了它的类。这种模式特别适用于一个对象的行为依赖于它的状态,并且状态数量较多、条件判断复杂的情况。
状态模式的核心思想
将与特定状态相关的行为封装到独立的状态类中,对象本身持有一个状态对象的引用,当状态变化时,只需切换该引用指向新的状态对象,调用行为时委托给当前状态对象处理。
这样做的好处是避免了大量 if-else 或 switch-case 判断语句,使代码更清晰、易于扩展和维护。
基本结构与实现步骤
状态模式通常包含三个核心部分:
立即学习“C++免费学习笔记(深入)”;
- Context(上下文):持有当前状态对象的实例,对外提供接口,将状态相关操作委托给状态对象。
- State(抽象状态):定义状态接口,所有具体状态类实现这个接口。
- ConcreteState(具体状态):实现特定状态下的行为逻辑,必要时可切换 Context 的状态。
下面是一个简单的例子,模拟电灯的开关状态:
#includeusing namespace std; // 抽象状态类 class LightState { public: virtual ~LightState() = default; virtual void pressSwitch(class Light* light) = 0; }; // 上下文类 class Light { private: LightState* currentState; public: explicit Light(LightState* state) : currentState(state) {} ~Light() { delete currentState; } void setState(LightState* state) { if (currentState) delete currentState; currentState = state; } void pressSwitch() { currentState->pressSwitch(this); } }; // 具体状态类 - 关闭状态 class OffState : public LightState { public: void pressSwitch(Light* light) override { cout << "Turning on the light.\n"; light->setState(new OnState()); } }; // 具体状态类 - 开启状态 class OnState : public LightState { public: void pressSwitch(Light* light) override { cout << "Turning off the light.\n"; light->setState(new OffState()); } };
使用示例:
int main() {
Light* light = new Light(new OffState());
light->pressSwitch(); // 输出: Turning on the light.
light->pressSwitch(); // 输出: Turning off the light.
light->pressSwitch(); // 输出: Turning on the light.
delete light;
return 0;
}状态模式的优点与适用场景
优点:
- 消除庞大的条件分支语句,提升可读性。
- 状态逻辑分离,符合单一职责原则。
- 新增状态方便,符合开闭原则。
适用场景:
- 一个对象存在多个状态,且行为随状态变化而变化。
- 状态转换逻辑复杂,包含嵌套判断。
- 希望将状态相关的操作局部化,便于管理和测试。
注意事项与常见问题
使用状态模式时需注意以下几点:
- 状态切换时注意内存管理,避免泄漏(如上例中 delete 旧状态)。
- 若状态对象无内部数据,可考虑使用单例模式共享实例,减少开销。
- 状态之间跳转逻辑应清晰,避免循环依赖或非法转移。
- Context 与 State 相互引用时小心析构顺序,防止野指针。
基本上就这些。状态模式通过对象组合代替条件判断,让状态变化变得灵活自然,在游戏开发、UI控制、通信协议等场景中非常实用。掌握它能显著提升复杂状态逻辑的代码质量。










