design patterns · high
State Pattern
State is a behavioral GoF pattern that lets an object change its behavior when its internal state changes, so it appears to change class. Each state becomes a class implementing a common State interface; the Context (e.g. Doc) holds a pointer to the current state and delegates operations to it (publish() calls state_->publish(*this)). Each concrete state implements the operation and performs the transition by calling context.setState(next) — Draft→Moderation→Published — so transition logic is distributed into the states, each knowing only its valid next states. This eliminates the repeated if/else-on-state switch in every method and is Open/Closed (adding a state is adding a class). Costs: more classes and a heap allocation per transition unless stateless states are cached/shared (flyweight). It is structurally identical to Strategy but differs in intent — Strategy is selected by the client and stays fixed for the task, while State swaps itself at runtime as the workflow advances. Compared to a std::variant state machine, State is the open, polymorphic (vtable, heap) form for extensible state sets, whereas variant suits a closed set with value semantics and visit-based exhaustiveness.
State (behavioral): make each state a class implementing a shared interface; the Context delegates the operation to its current state, and each state performs its behavior and transitions via setState(next) — removing if/else-on-state sprawl and making states Open/Closed. Same structure as Strategy but Strategy is client-picked/fixed while State self-transitions at runtime; vs std::variant (closed set, value semantics) State is the open/polymorphic form.
The code
// State — let an object change behavior when its internal state changes.// Each state is a CLASS; the context delegates to the current one.class Doc;struct State { virtual void publish(Doc&) = 0; // same action, state-specific virtual ~State() = default;};
class Doc { std::unique_ptr<State> state_;
public: Doc(); void setState(std::unique_ptr<State> s) { state_ = std::move(s); } void publish() { state_->publish(*this); } // delegate};
struct Draft : State { void publish(Doc& d) override;}; // -> Moderationstruct Moderation : State { void publish(Doc& d) override;}; // -> Publishedstruct Published : State { void publish(Doc& d) override { /* no-op */ }};
void Draft::publish(Doc& d) { d.setState(std::make_unique<Moderation>());}void Moderation::publish(Doc& d) { d.setState(std::make_unique<Published>());}What this lesson walks through
- 01Intent — behavior driven by state, no giant switch
- 02Structure — Context delegates to a State object
- 03Each state owns its own transitions
- 04Gotcha — State vs Strategy
The State pattern lets an object change its behavior when its internal state changes — it appears to change class. Instead of a sprawling switch(state) in every method, each state is its own object that knows how to behave.
See it animated — step by step, at your own pace
Unlock the full interactive walkthrough of State Pattern and 100+ animated C++ interview lessons.