[Home]
[Edit this page]
[Recent Changes]
[Special Pages]
[Help]
CppState
A State enables you to change a class its state. Instead of using internal type switching, you let polymorphism sort the State-dependent function out.
In this Design Pattern there are two players:
The State can be seen as an internal state-dependent switch, in which not the entire class changes to change its behaviour.
The State is related to the Strategy Design Pattern, except that Strategy does not have a pointer to its Context. Therefore, a State can only be used for one Context, whereas the Strategy can be used by multiple classes.
Below is a simple example. It describes a class with two member variables and two States. These States are 'plus' and 'minus'. It can change its state and then either adds or substracts these two numbers. In this example, the State is a friend class of its context, but this need not to be the case.
For an example of this same state seperated properly over multiple files, click here
[Edit this page] [Page history] [What links here] [Discuss this topic] [Printer Friendly]
CppState
(C++) State
A Design Pattern [1].A State enables you to change a class its state. Instead of using internal type switching, you let polymorphism sort the State-dependent function out.
In this Design Pattern there are two players:
- the Context
- the State
The State can be seen as an internal state-dependent switch, in which not the entire class changes to change its behaviour.
The State is related to the Strategy Design Pattern, except that Strategy does not have a pointer to its Context. Therefore, a State can only be used for one Context, whereas the Strategy can be used by multiple classes.
Below is a simple example. It describes a class with two member variables and two States. These States are 'plus' and 'minus'. It can change its state and then either adds or substracts these two numbers. In this example, the State is a friend class of its context, but this need not to be the case.
For an example of this same state seperated properly over multiple files, click here
enum enumState{ plus, minus}; //--------------------------------------------------------------------------- // CLASS DECLARATION // (for in .H file) //--------------------------------------------------------------------------- class StateBase; //Forward declaration class StatePlus; //Forward declaration class StateMinus; //Forward declaration class Context { friend class StateBase; friend class StatePlus; friend class StateMinus; public: Context(); void setState(const enumState&); void doIt() const; private: std::auto_ptr<StateBase> mState; const int mValue1; const int mValue2; }; class StateBase { public: StateBase() {} //Empty constructor virtual int doIt() const = 0; protected: Context * mContext; //Pointer to the Context }; class StatePlus : public StateBase { public: StatePlus(Context *); //Can only initialize with Context pointer int doIt() const; }; class StateMinus : public StateBase { public: StateMinus(Context *); //Can only initialize with Context pointer int doIt() const; }; //--------------------------------------------------------------------------- // CLASS DEFINITION // (for in .CPP file) //--------------------------------------------------------------------------- Context::Context() : mState(new StatePlus(this)), //Initializes State mValue1(std::rand()%100), //Random number mValue2(std::rand()%100) //Random number { //Nothing } //--------------------------------------------------------------------------- void Context::setState(const enumState& state) { switch(state) { case plus : mState.reset(new StatePlus(this)); break; case minus: mState.reset(new StateMinus(this)); break; default: assert(!"Unknown state"); std::exit(1); //Use of assert to get line number } } //--------------------------------------------------------------------------- void Context::doIt() const { //The function doIt is delegated to the State //Therefore this function is State-dependent std::cout << "Doing it with " << mValue1 << " and " << mValue2 << ": " << mState->doIt() << std::endl; } //--------------------------------------------------------------------------- StatePlus::StatePlus(Context * context) { mContext = context; } //--------------------------------------------------------------------------- StateMinus::StateMinus(Context * context) { mContext = context; } //--------------------------------------------------------------------------- int StatePlus::doIt() const { //Adds the two values of Context return (mContext->mValue1 + mContext->mValue2); } //--------------------------------------------------------------------------- int StateMinus::doIt() const { //Adds the two values of Context return (mContext->mValue1 - mContext->mValue2); } //--------------------------------------------------------------------------- int main(int argc, char* argv[]) { //Make a Context const std::auto_ptr<Context> myContext(new Context); //Set the State myContext->setState(plus); //Do the State-dependent function myContext->doIt(); //Set the State myContext->setState(minus); //Do the State-dependent function myContext->doIt(); //Program done }
- include <iostream>
- include <memory>
- include <cassert>
Code links
- #include
- scope operator'::'
- stream out operator '<<'
- argc
- argv
- assert
- auto_ptr
- class
- char
- const
- cout
- endl
- enum
- friend
- iostream
- #include
- int
- main
- operator<<
- operator::
- public
- return
- std
- std::auto_ptr
- std::cout
- std::endl
State in other programming languages
- (none on CodePedia yet)
References
1) Erich Gamma, Richard Helm, Ralph Johnson, John Vlissides. Design Patterns. Publisher: Addison-Wesley Professional; 1st edition (January 15, 1995). ISBN: 0201633612[Edit this page] [Page history] [What links here] [Discuss this topic] [Printer Friendly]
