I have already discussed how the state pattern can be implemented in C++.

Here is one of my earlier blog post on State Design Pattern.

https://som-itsolutions.blogspot.com/2022/05/the-state-design-pattern-in-c-using.html

But this time I have implemented the State Pattern using boost’s pointer.

The Mamma class here has a shared_ptr reference to the chicken state and similarly the ChickenState class has a share_ptr reference to Mamma. As there is cyclic dependency, so we have to be very very careful of memory leak even though we have used the boost’s pointer.

The result of the application is like this:

chicken is now getting cleaned

Moving to the cleaned state...

Chicken is getting marinated

Chicken is finished marinating now moving on to the Marinated States

Inside cleanedstate destructor

destructor of chickenstate

chicken is getting cooked

chicken is properly cooked... So moving to the next state...

Inside Marinated state destructor

destructor of chickenstate

Chicken is ready enjoy the food

now everyone eat

this is the last state.... exiting...

Inside cooked state destructor

destructor of chickenstate

Uncleaned state destructor

destructor of chickenstate

Inside Mamma destructor

If you delve into it, you will find all the classe’s destructor has been called - meaning that there is no memory leak in this application.

Please have a look at the startPreparation method of Mamma. This is as below:

void startPreparation(){

        chicken->clean();

        chicken->marinate();

        chicken->cook();

        chicken->serve();

        chicken.reset();

        }

Please have a look at the reset method that we have called on the Chicken object just at the end of the method. This ensures that the reference count of the managed object becomes zero and then only Mamma’s destructor is called.

Here is the source code of this application

ChickenState

#ifndef CHICKENSTATE_H_

#define CHICKENSTATE_H_

#include <iostream>

#include <memory>

class Mamma;

using namespace std;

class ChickenState {

protected:

        shared_ptr<Mamma> mamma;

public:

        ChickenState(){

                mamma = nullptr;

        }

        ChickenState(shared_ptr<Mamma> inMamma){

                mamma = inMamma;

        }

        virtual ~ChickenState(){

                cout<<"destructor of chickenstate"<<endl;

        }

        virtual void clean(){

        }

        virtual void marinate(){

        }

        virtual void cook(){

        }

        virtual void serve(){

        }

};

#endif /* CHICKENSTATE_H_ */

—-------------------------------------------------------

Mamma

#ifndef MAMMA_H_

#define MAMMA_H_

#include <memory>

#include <iostream>

#include "UncleanedState.h"

#include "CleanedState.h"

class ChickenState;

using namespace std;

class Mamma {

private:

        shared_ptr<ChickenState> chicken;

        //ChickenState* chickenState;

public:

        Mamma(){

                //chicken = nullptr;

        }

        virtual ~Mamma(){

                cout<<"Inside Mamma destructor"<<endl;

        }

        void changeChickenState(shared_ptr<ChickenState> nextstate){

                        chicken = std::move(nextstate);

        }

        void startPreparation(){

                chicken->clean();

                chicken->marinate();

                chicken->cook();

                chicken->serve();

                chicken.reset();

        }

};

#endif /* MAMMA_H_ */

—----------------------------------------------

Uncleaned State

#ifndef UNCLEANEDSTATE_H_

#define UNCLEANEDSTATE_H_

#include "ChickenState.h"

#include "CleanedState.h"

class Mamma;

using namespace std;

class UncleanedState: public ChickenState {

public:

        bool isUncleanStateDone;

public:

        UncleanedState(){

                isUncleanStateDone = false;

        }

        UncleanedState(shared_ptr<Mamma> inMamma){

                mamma = inMamma;

        }

        virtual ~UncleanedState(){

                cout<<"Uncleaned state destructor"<<endl;

        }

        void clean(){

                if(isUncleanStateDone == false){

                        cout<<"chicken is now getting cleaned"<<endl;

                        cout<<"Moving to the cleaned state..."<<endl;

                        shared_ptr<ChickenState> nextState = shared_ptr<ChickenState>(new CleanedState(mamma));

                        mamma->changeChickenState(nextState);

                        isUncleanStateDone = true;

                }

        }

};

#endif /* UNCLEANEDSTATE_H_ */

—---------------------------------------------------------------------------------------

Cleaned State

#ifndef CLEANEDSTATE_H_

#define CLEANEDSTATE_H_

#include "ChickenState.h"

#include "MarinatedState.h"

#include "Mamma.h"

class Mamma;

using namespace std;

class CleanedState: public ChickenState {

public:

        bool isCleanedStateDone;

public:

        CleanedState(){

                isCleanedStateDone = false;

        }

        CleanedState(shared_ptr<Mamma> inMamma){

                mamma = inMamma;

        }

        virtual ~CleanedState(){

                cout<<"Inside cleanedstate destructor"<<endl;

        }

        void marinate(){

                if(isCleanedStateDone == false){

                        cout<<"Chicken is getting marinated"<<endl;

                        cout<<"Chicken is finished marinating now moving on to the Marinated States"<<endl;

                        shared_ptr<ChickenState> nextState = shared_ptr<ChickenState>(new MarinatedState(mamma));

                        mamma->changeChickenState(nextState);

                        isCleanedStateDone = true;

                }

        }

};

#endif /* CLEANEDSTATE_H_ */

—-----------------------------------------

Marinated State

#ifndef MARINATEDSTATE_H_

#define MARINATEDSTATE_H_

#include "ChickenState.h"

#include "CookedState.h"

#include "Mamma.h"

class Mamma;

using namespace std;

class MarinatedState: public ChickenState{

public:

        bool isMarinatedStateDone;

        MarinatedState(){

                isMarinatedStateDone = false;

        }

        MarinatedState(shared_ptr<Mamma> inMamma){

                mamma = inMamma;

        }

        virtual ~MarinatedState(){

                cout<<"Inside Marinated state destructor"<<endl;

        }

        void cook(){

                if(isMarinatedStateDone == false){

                        cout<<"chicken is getting cooked"<<endl;

                        cout<<"chicken is properly cooked... So moving to the next state..."<<endl;

                        shared_ptr<ChickenState> nextState = shared_ptr<ChickenState>(new CookedState(mamma));

                        mamma->changeChickenState(nextState);

                        isMarinatedStateDone = true;

                }

        }

};

#endif/* MARINATEDSTATE_H_ */

—--------------------------------------------------------------------------------------

Cooked State

#ifndef COOKEDSTATE_H_

#define COOKEDSTATE_H_

#include "ChickenState.h"

class Mamma;

class CookedState: public ChickenState {

public:

        CookedState(){

        }

        CookedState(shared_ptr<Mamma> inMamma){

                mamma = inMamma;

        }

        virtual ~CookedState(){

                cout<<"Inside cooked state destructor"<<endl;

        }

        void serve(){

                cout<<"Chicken is ready enjoy the food"<<endl;

                cout<<"now everyone eat"<<endl;

                cout<<"this is the last state.... exiting..."<<endl;

        }

};

#endif /* COOKEDSTATE_H_ */

—---------------------------------------------------------------------------

Main

#include "UncleanedState.h"

int main(){

        shared_ptr<Mamma> mamma = shared_ptr<Mamma>(new Mamma);

        shared_ptr<ChickenState> firstState = shared_ptr<ChickenState>(new UncleanedState(mamma));

        mamma->changeChickenState(firstState);

        mamma->startPreparation();

        return 0;

}