Is this Polymorphism and is this bad practice? - c++

I'm setting up a State system for my game.
class State
{
protected:
enum State_
{
STATE_INTRO,
STATE_GAME,
STATE_PAUSE,
STATE_CUTSCENE,
};
public:
State();
virtual void run(State_) = 0;
virtual ~State(); // virtual destructor cus we will be inheriting this class
};
I then have inherited classes which represent each state
class IntroState : public State
{
public:
void run(State_ STATE);
};
I want the run function to have different functionality based off of what state the game is in, is it bad practice to achieve that like this:
void IntroState::run(State_ STATE)
{
if (STATE == STATE_INTRO)
{
// load the intro
}
}
I'm not sure how else to do this, thanks (and keep in my mind I'm JUST learning about states so I might be completely off here)

To expand on my comment, here is a possible approach (improvements are appreciated):
class Game {
//... Initialize all State-derived classes in constructor and put them in states (not shown)
vector<unique_ptr>> states;
State_ currentState {STATE_INTRO};
State_ nextState {STATE_INTRO};
public:
void setNextState(State_ state ) {nextState = state;}
void Play() {
for(;;) { //endless loop
if (!states[currentState]->run()) return;//stopping when run returns false
currentState = nextState;
}
}
};
And run could look like this:
class IntroState : public State {
//...
void run(Game& game) {
// do stuff
game.setNextState(STATE_GAME);
return true;
}
};
Of course, you need to figure out the include order, and you'll need to forward-declare Game in State.hpp (the code shown here only shows the central idea). Also, the implementations of run and Play should of course be in seperate .cpp files (didn't do that here so this example wouldn't get too long)

I think you don't need polymorphism in your case since you will only have one State class in your application (correct me if I'm wrong).
You're run function would look like this:
void run(State_ state)
{
switch (state)
{
case STATE_INTRO:
doIntro();
case STATE_BLAH:
doBlah();
// fill all you states...
}
}
void doIntro()
{
// do something for the intro
}
void doBlah()
{
// do something for blah
}
Now if you really wanna get fancy and remove the switch statement:
class State
{
private:
void doA() {}
void doB() {}
enum State_
{
A = 0,
B,
END_
};
std::function<void(void)> functions[END_];
public:
State()
{
functions[A] = std::bind(&State::doA, this);
functions[B] = std::bind(&State::doB, this);
}
void run(State_ state)
{
functions[state]();
}
};

Related

State Machine Change State

I'm continuously running into the same problem, and can't fix it even when looking through tutorials.
I've "set up" my State machine, but I can't transition between states.
Here is my StateMachine:
class StateMachine
{
State* m_State;
public:
StateMachine();
~StateMachine();
void changeState(State* state);
};
And here is an example State:
class A : State
{
public:
A();
~A();
void handleInput(int a);
}
If I pass a = 1 into A::handleInput() I want to transition to State B. But when I implement it I can't access the StateMachine from A::handleInput(), making me scrub my head in agony.
But when I implement it I can't access the StateMachine from A::handleInput()
Well, that's a well known problem with the State Pattern, that there's no mention how to keep the state classes in track with an enclosing State Machine.
IMO, that's one of the valid use cases to consider the StateMachine class as being implemented as a Singleton.
This way it's instance would be accessible from any Stateclass implementation.
As I'm talking in terms of Design Patterns here, the State classes could be designed with help of the Flyweight Pattern, since they're usually stateless themselves.
I've once driven all that into a c++ template framework, which abstracts the interfaces of State and State Machine (see link below).
Here's a short code example by these means:
StateMachine.h
struct State {
virtual void handleInput(int x) = 0;
virtual ~State() {} = 0;
};
class StateMachine {
State* m_State;
StateMachine();
public:
static StateMachine& instance() {
static StateMachine theInstance;
return theInstance;
}
void changeState(State* state) {
m_State = state;
}
void triggerInput(int x) {
m_State->handleInput(x);
}
};
StateA.h
#include "StateMachine.h"
class StateB;
extern StateB* stateB;
class StateA : public State {
public:
virtual ~StateA() {}
virtual void handleInput(int x) {
if(x == 1) {
// Change to StateB
StateMachine::instance.changeState(stateB);
}
else {
// Do something with x
}
}
};
I omit the definition od StateB here, should be the same manner as StateA.
References:
C++ Singleton Design Pattern
State machine template class framework for C++
I've taken a look at the Sourcemaking example and for me the implementation example really sucks; having to create new instances upon every state change:
https://sourcemaking.com/design_patterns/state/cpp/1
Personally as someone who's designed state machines in electronics with JK flip flops, I would use a similar but semantically different approach. The complexity in state machines involves the action performed according to the state and input; typically in C you would do this with lots of switch statements and possibly arrays describing how to handle the current state and new input aka event.
So to me the OO approach to this would be to model the event handler. This would have an interface which describes the format of the inputs. You then have different implementations of that interface for each different state. With that, the state machine can simply implement a collection of states to event handlers - array, vector or map. Although the handlers still may contain case statements, the overall spaghettiness is very much reduced. You can easily extend the design with new state handlers as and when necessary:
So you could have something like this:
#include <map>
typedef enum
{
//TODO : state list, e.g.
eOff,
eOn
}
teCurrentState;
typedef struct
{
//TODO : Add inputs here, e.g.
bool switch1;
}
tsInputDesc;
typedef struct
{
//TODO : Add outputs here, e.g.
bool relay1;
}
tsOutputDesc;
// ------------------------------------------------
class IEventHandler
{
public:
virtual ~IEventHandler() {}
// returns new state
virtual teCurrentState handleInput(tsInputDesc const& input, tsOutputDesc& output) = 0;
};
// ------------------------------------------------
class OnStateHandler : public IEventHandler
{
public:
virtual teCurrentState handleInput(tsInputDesc const& input, tsOutputDesc& output) override
{
//TODO : IMPLEMENT
teCurrentState newState = TODO....
return (newState);
}
};
// ------------------------------------------------
class OffStateHandler : public IEventHandler
{
public:
virtual teCurrentState handleInput(tsInputDesc const& input, tsOutputDesc& output) override
{
//TODO : IMPLEMENT
teCurrentState newState = TODO....
return (newState);
}
};
// ------------------------------------------------
class StateMachine
{
protected:
teCurrentState mCurrentState;
std::map<teCurrentState, IEventHandler*> mStateHandlers;
void makeHandlers()
{
mStateHandlers[eOff] = new OffStateHandler();
mStateHandlers[eOn] = new OnStateHandler();
}
public:
StateMachine()
{
makeHandlers();
mCurrentState = eOff;
}
void handleInput(tsInputDesc const& input, tsOutputDesc output)
{
teCurrentState newState = mStateHandlers[mCurrentState]->handleInput(input, output);
mCurrentState = newState;
}
};
// ------------------------------------------------
void runFsm()
{
StateMachine fsm;
tsInputDesc input;
tsOutputDesc output;
bool alive = true;
while (alive)
{
// TODO : set input according to....inputs (e.g. read I/O port etc)
fsm.handleInput(input, output);
// TODO : use output
}
}

Provide PV function content when constructing object in C++

In Java you can create an object whilst at the same time providing (or overloading) abstract functions within the object, thus:
ActionListener al = new ActionListener() {
public void actionPerformed(ActionEvent e) {
// Whatever in here
}
};
I really like that way of doing it, and was wondering if there was some similar construct in C++.
Basically I want a base class with a couple of PV functions declared in it (amongst other stuff), and the user to create an instance of that class whilst at the same time providing the body of the PV functions.
I know I could create child classes, but that seems a little clunky for what I need, where each child class would be unique and only be used to make one instance each.
I have thought about providing lamdas to the constructor and using those instead of actual member functions, but that really seems messy and hard for a novice user to get their head around - not to mention that it would be too rigid (I'd also like to be able to override some non-pure virtual functions optionally).
So is child classes the only way to go, or is there some lesser-known construct in some newer C++ standard that I don't know about that could do what I want?
To expand a little - the idea is to have a class like:
class Thread {
// other stuff
public:
virtual void setup() = 0;
virtual void loop() = 0;
// other functions, some virtual but not pure
};
Thread threadOne {
void setup() {
// Init code for this thread
}
void loop() {
// Run code for this thread
}
};
Thread threadTwo {
void setup() {
// Init code for this thread
}
void loop() {
// Run code for this thread
}
};
Obviously not that syntax, but it gives you an idea of how I'd like to use the class.
It's intended to be run on an embedded system with a slimmed-down C++ implementation (it's g++ but without the full STL). End users aren't the brightest bunch, so it has to be kept as simple to understand as possible.
Anonymous child classes are the closest to what I'd like (though still not perfect). I can use CPP macros to help abstract some of the class implementation syntactic sugar which would help.
Here's a compilable construct I have come up with. Is there anything "wrong" with this approach given the constraints above?
#define THREAD(NAME, CONTENT) class : public Thread {\
public:\
CONTENT\
} NAME;
class Thread {
private:
uint32_t stack[256]; // 1kB stack
volatile bool _running;
public:
virtual void setup() = 0;
virtual void loop() = 0;
void start();
void stop();
uint8_t state();
static void spawn(Thread *thr);
void threadRunner();
};
void Thread::spawn(Thread *thread) {
thread->threadRunner();
}
void Thread::start() {
Thread::spawn(this);
}
void Thread::threadRunner() {
_running = true;
setup();
while (_running) {
loop();
}
}
void Thread::stop() {
_running = false;
}
uint8_t Thread::state() {
return 0;
}
THREAD(myThread,
void setup() override {
}
void loop() override {
}
)
void setup() {
myThread.start();
}
void loop() {
}
Obviously it doesn't actually do anything yet - the whole of the threading back-end is a separate issue, and will be ported over from some existing code I wrote a few years back. I am mainly interested in simplifying the interface for the end user.
There is multiple possibilities, but I'd stick with something simple and versatile: callbacks and lambdas instead of virtual function and inheritance.
class ActionListener
{
std::function<void(int)> _action_performed;
public:
template<class CB>
ActionListener(CB cb) : _action_performed(cb) {}
void click() { _action_performed(0); }
};
int main()
{
ActionListener al([](int n) { std::cout << "Action Performed #" << n << "\n"; });
al.click(); // prints "Action Performed #0"
}
live demo
I'd also like to be able to override some non-pure virtual functions optionally
Which, semantically speaking, means providing a default behavior. This is possible:
ActionListener(CB cb) : _action_performed(cb) {} // construct an AL with the given callback
ActionListener() : _action_performed(default_action_performed) {} // construct an AL with a default callback
void default_action_performed(int n) { /*...*/ }
well, as you already mentioned, one way would be child classes.
another way would be providing some std::functions (or lambdas), either in the constructor or have some set functions.
store the function as a member and call this once your "virtual" member function is called: If you want it optional:
class MyBase
{
public:
MyBase();
void SetFunc(const std::function<int()>& myFun)
{
m_myFun = myFun;
}
int MyVirtFunc()
{
if(m_myFun)
{
return m_myFun();
}
else
{
return 42;
}
}
private:
std::function<int()> m_myFun;
}
if you want the functions given mandatory, put them in the constructor:
class MyBase
{
public:
MyBase(const std::function<int()>& myFun)
: m_myFun(myFun) {}
int MyVirtFun() { return m_myFun(); }
private:
const std::function<int()> m_myFun;
}

Create a temporary interface into an object?

I have an object "World obj;" that has a normal interface of methods for it's typical funcitonality, but I want to have an additional interface of methods specifically for initializing that should only be visible when I specifically need them.
An example might be like this:
class World{
public:
void draw();
void update();
void normalStuff();
void addATree(); // this should not be ordinarily available or visible,
void addACar(); // calling this might break the object
void addAClown();// if it's not in a ready state for it
private:
int m_data;
};
Is there a way to relatively hide addATree(); etc in a way that makes sense? Ideally the mechanism for revealing those methods would also put the object into a ready state for them, or at least fault if it's not possible.
Different approaches would be possible:
Don't change the code, just change the spec
No need to change the code. Change the API specification and if the caller throws garbage in he gets garbage out.
Make the functions check if they are allowed
Always safe.
class World{
public:
...
void addAClown() {
if(not allowed)
throw error or crash or output error message or just return;
else {
do the work;
}
}
private:
int m_data;
};
Write a function that only exposes the Interface if allowed
You can't protect against someone getting the interface early and use it longer than allowed.
You could extract the interface functions into a separate class.
class WorldInterfaceToProtect {
public:
void addATree() = 0; // this should not be ordinarily available or visible,
void addACar() = 0; // calling this might break the object
void addAClown() = 0;// if it's not in a ready state for it
};
then the main class can protect these functions.
class World : protected WorldInterfaceToProtect {
public:
void draw();
void update();
void normalStuff();
protected:
void addATree(); // this should not be ordinarily available or visible,
void addACar(); // calling this might break the object
void addAClown();// if it's not in a ready state for it
private:
int m_data;
};
You then need to add a function that exposes the interface.
class World ... {
public:
WorldInterfaceToProtect *GetInterface() { return allowed_cond ? this : nullptr; }
...
}
Separate the class itself and the builder
This only helps if the functions to be called are only allowed during construction and not later. Depending on the design of the builder you can get a good protection.
class World{
friend class WorldBuilder;
public:
void draw();
void update();
void normalStuff();
protected:
void addATree(); // this should not be ordinarily available or visible,
void addACar(); // calling this might break the object
void addAClown();// if it's not in a ready state for it
private:
int m_data;
};
class WorldBuilder {
static World *Build(...);
}
Perhaps split the world into more composable parts:
struct WorldInterface
{
virtual void draw() = 0;
virtual void update() = 0;
virtual void normalStuff() = 0;
};
class World : public WorldInterface
{
public:
void draw() override { /* actual drawing here */};
void update() override {};
void normalStuff() override {};
private:
int m_data;
};
class TreeWorld : public WorldInterface
{
public:
// takes a reference to the actual world engine and defers work to
// that
TreeWorld(World& worldEngine) : worldEngine_(worldEngine) {}
void draw() override { worldEngine_.get().draw(); };
void update() override { worldEngine_.get().update(); };
void normalStuff() override { worldEngine_.get().normalStuff(); };
void addATree() {
//do tree/world interaction here
}
private:
std::reference_wrapper<World> worldEngine_;
};
class CarWorld : public WorldInterface
{
public:
// takes a reference to the actual world engine and defers work to
// that
CarWorld(World& worldEngine) : worldEngine_(worldEngine) {}
void draw() override { worldEngine_.get().draw(); };
void update() override { worldEngine_.get().update(); };
void normalStuff() override { worldEngine_.get().normalStuff(); };
void addACar() {
//do car/world interaction here
}
private:
std::reference_wrapper<World> worldEngine_;
};
extern void play_tree_game(TreeWorld world);
extern void play_car_game(CarWorld world);
int main()
{
World worldEngine;
// initialise engine here
// play tree-phase of game
play_tree_game(TreeWorld(worldEngine));
// play car phase of game
play_car_game(CarWorld(worldEngine));
}
Good answers all around, I'll just add this because it was missing(?)
class World{
public:
void draw();
void update();
void normalStuff();
private:
int m_data;
};
class BuildableWorld : public World
{
public:
void addATree();
void addACar();
void addAClown();
};
Use the BuildableWorld at initialization phase and then just give a pointer to the base class type for others to use.
Sure, you need some way to give the "built" data for the base class to access, but that was not the issue here, right?
an alternative approach that has not been mentioned so far, may be to let addX() functions take parameters whose existence implies that World is in a valid state. Say, if you cannot add trees to a world without water, let World return an (optional) water object to pass to addTree ... in other words, you need to properly formalize World invariants:
class World{
public:
void normalStuff();
auto getAvaliableWaterBuckets() -> optional<WaterBuckets>;
auto getAvaliableSoil() -> optional<SoilPack>;
//...
void addATree( WaterBuckets&&, SoilPack&& );
//...
};
// in the meanwhile, in user land:
if( auto water = world->getAvaliableWaterBuckets() )
if( auto soil = world->getAvaliableSoil() )
world->addTree( std::move(*water), std::move(*soil) );
else
world->recycleWater( std::move(*water) );
the benefit of this approach is that the user is not forced to think about world state validity ( an error prone task ), he just thinks about what he needs in order to add a tree ( simpler, hard to use incorrectly ). Moreover, this scales well because addX() functions can share different objects ( addFlowers needs water, ... ) enabling the correct management of a possibly complex internal world state.
Of course, IMHO, if you need to use addX() strictly on world construction only ( and you don't plan to add trees later ), then the factory approach already mentioned in the comments seems the way to go ...

Event-based Game engine based on polymorphism of Entities

I would like to create a simple framework for throwing and catching events in a game. Events could be things like a Collision which (according to the type) can take several arguments (note that every Event type may take another amount of arguments, not just two as in the example).
I would then like to implement functions/classes/... to deal with a Collision, based on polymorphism. This example should illustrate the problem:
#include <iostream>
#include <vector>
class Entity {};
class Player: public Entity {};
class Bomb: public Entity {
public:
bool exploded;
};
class MineSweeper: public Entity {};
// For now, I only included Collisions, but I eventually want to extend it to
// more types of Events too (base class Event, Collision is derived class)
void onCollision(Player* p, Bomb* b) {
if (! b->exploded) {
std::cout << "BOOM";
b->exploded = true;
}
}
void onCollision(Entity* e, Entity* f) {
std::cout << "Unhandled collision\n";
}
// Possibility for Collision between Minesweeper and Bomb later
class Game {
public:
std::vector<Entity*> board; // some kind of linear board
Game() {
board = {new Player, new Bomb, new MineSweeper};
}
void main_loop() {
onCollision(board[0], board[1]); // player and bomb!
onCollision(board[1], board[2]);
}
};
int main() {
Game g;
g.main_loop();
}
Note that I understand perfectly well why the above code doesn't work as intended, I included this example solely to illustrate my problem better.
The above example uses functions for the events, but I'm perfectly fine with classes or any other solution that is maintainable.
I hope it is clear that I would like C++ to decide which event handler to use based on the types of the arguments (presumably at runtime).
My question: How can I do this in C++? An example would be appreciated.
(not my question: fix my code please)
user2864740 provided enough clues for me to find a solution myself. Multiple dispatch was indeed the missing piece.
The following code works as intended, making use of dynamic_cast to dispatch correctly.
#include <iostream>
#include <vector>
class Entity {
virtual void please_make_this_polymorphic() {}
// although this function does nothing, it is needed to tell C++ that it
// needs to make Entity polymorphic (and thus needs to know about the type
// of derived classes at runtime).
};
class Player: public Entity {};
class Bomb: public Entity {
public:
bool exploded;
};
class MineSweeper: public Entity {};
// For now, I only included Collisions, but I eventually want to extend it to
// more types of Events too (base class Event, Collision is derived class)
void onCollision(Player* p, Bomb* b) {
if (!b->exploded) {
std::cout << "BOOM\n";
b->exploded = true;
}
}
void onCollision(Entity* e, Entity* f) {
std::cout << "Unhandled collision\n";
}
void dispatchCollision(Entity* e, Entity* f) {
Player* p = dynamic_cast<Player*>(e);
Bomb* b = dynamic_cast<Bomb*>(f);
if (p != nullptr && b != nullptr) {
onCollision(p, b); // player and bomb
} else {
onCollision(e, f); // default
}
}
class Game {
public:
std::vector<Entity*> board; // some kind of linear board
Game() {
board = {new Player, new Bomb, new MineSweeper};
}
void main_loop() {
dispatchCollision(board[0], board[1]); // player and bomb
dispatchCollision(board[1], board[2]);
}
};
int main() {
Game g;
g.main_loop();
}
Although it works, I'd like to point out some problems with this code:
Manual editing of dispatchCollision needed when adding new Collisions.
Currently, the dispatcher using a simple kind of rule-based system. (Does it fit rule 1? What about rule 2? ...) When adding loads of different functions it needs to dispatch, that may have an impact on the performance.
A collision between A and B should be the same as a collision between B and A, but that isn't properly handled yet.
Solving these problems is not necessarily in the scope of this question IMHO.
Also, the example given should work just as well for more than 2 arguments. (Multiple dispatch, not just double dispatch.)
You should decide first what event subscription model you need.
It could be signal/slot mechanism and you can find plenty of libraries:
https://code.google.com/p/cpp-events/ , http://sigslot.sourceforge.net/ and the like.
Or it could be bubbling/sinking events like in HTML DOM when event gets propagated on parent/child chain ( from event source element to its containers).
Or even other schema.
It is quite easy to create whatever you need with std::function holders in modern C++.
Maybe a good structure for your case could be something like this:
class Entity{
public:
virtual int getType() = 0;
};
enum EntityTypes {
ACTOR,
BOMB,
MINESWEEPER,
};
class Actor : public Entity{
public:
virtual int getType() {return int(ACTOR);}
void applyDamage() {
std::cout << "OUCH";
}
};
class Bomb : public Entity{
public:
Bomb() : exploded(false) {}
virtual int getType() {return int(BOMB);}
void explode() {
this->exploded = true;
}
bool isExploded() {
return this->exploded;
}
protected:
bool exploded;
};
class MineSweeper : public Entity{
public:
virtual int getType() {return int(MINESWEEPER);}
};
class CollisionSolver {
public:
virtual solve(Entity* entity0, Entity* entity1) = 0;
};
class ActorBombCollisionSolver : public CollisionSolver {
public:
virtual solve(Entity* entity0, Entity* entity1) {
Actor* actor;
Bomb* bomb;
if (entity0->getType() == ACTOR && entity1->getType() == BOMB) {
actor = static_cast<Actor*>(entity0);
bomb = static_cast<Bomb*>(entity1);
}else if (entity1->getType() == ACTOR && entity0->getType() == BOMB) {
actor = static_cast<Actor*>(entity1);
bomb = static_cast<Bomb*>(entity0);
}else {
//throw error;
}
if (!bomb->isExploded()) {
bomb->explode();
actor->applyDamage();
}
}
};
class CollisionDispatcher {
public:
CollisionDispatcher() {
CollisionSolver* actorBombCollisionSolver = new ActorBombCollisionSolver;
this->solvers[ACTOR][BOMB] = actorBombCollisionSolver;
this->solvers[BOMB][ACTOR] = actorBombCollisionSolver;
// this part wouldn't be necessary if you used smart pointers instead of raw... :)
this->solvers[BOMB][MINESWEEPER] = 0;
this->solvers[MINESWEEPER][BOMB] = 0;
this->solvers[ACTOR][MINESWEEPER] = 0;
this->solvers[MINESWEEPER][ACTOR] = 0;
}
void dispatchCollision(Entity* entity0, Entity* entity1) {
CollisionSolver* solver = this->solvers[entity0->getType()][entity1->getType()];
if (!solver) {
return;
}
solver->solve(entity0, entity1);
}
protected:
unordered_map<int, unordered_map<int, CollisionSolver*> > solvers;
};
class Game {
public:
std::vector<Entity*> board; // some kind of linear board
Game() : dispatcher(new CollisionDispatcher)
{
board = {new Player, new Bomb, new MineSweeper};
}
void main_loop() {
dispatcher->dispatchCollision(board[0], board[1]);
dispatcher->dispatchCollision(board[0], board[2]);
dispatcher->dispatchCollision(board[1], board[2]);
}
protected:
CollisionDispatcher* dispatcher;
};
int main() {
Game g;
g.main_loop();
}
This way you can easily add new collision solvers, just define the class, and register t in the CollisionDispatcher constructor.
If you use smart pointers you won't need to set zeroes in the map entries not registered, but if you use raw pointers you have to set them to zero OR use unordered_map::find method instead of just grabbing the solver using operator []
Hope it helps!

Resolving a Forward Declaration Issue Involving a State Machine in C++

I've recently returned to C++ development after a hiatus, and have a question regarding
implementation of the State Design Pattern. I'm using the vanilla pattern, exactly as
per the GoF book.
My problem is that the state machine itself is based on some hardware used as part of
an embedded system - so the design is fixed and can't be changed. This results in a
circular dependency between two of the states (in particular), and I'm trying to
resolve this. Here's the simplified code (note that I tried to resolve this by using
headers as usual but still had problems - I've omitted them in this code snippet):
#include <iostream>
#include <memory>
using namespace std;
class Context
{
public:
friend class State;
Context() { }
private:
State* m_state;
};
class State
{
public:
State() { }
virtual void Trigger1() = 0;
virtual void Trigger2() = 0;
};
class LLT : public State
{
public:
LLT() { }
void Trigger1() { new DH(); }
void Trigger2() { new DL(); }
};
class ALL : public State
{
public:
ALL() { }
void Trigger1() { new LLT(); }
void Trigger2() { new DH(); }
};
// DL needs to 'know' about DH.
class DL : public State
{
public:
DL() { }
void Trigger1() { new ALL(); }
void Trigger2() { new DH(); }
};
class HLT : public State
{
public:
HLT() { }
void Trigger1() { new DH(); }
void Trigger2() { new DL(); }
};
class AHL : public State
{
public:
AHL() { }
void Trigger1() { new DH(); }
void Trigger2() { new HLT(); }
};
// DH needs to 'know' about DL.
class DH : public State
{
public:
DH () { }
void Trigger1() { new AHL(); }
void Trigger2() { new DL(); }
};
int main()
{
auto_ptr<LLT> llt (new LLT);
auto_ptr<ALL> all (new ALL);
auto_ptr<DL> dl (new DL);
auto_ptr<HLT> hlt (new HLT);
auto_ptr<AHL> ahl (new AHL);
auto_ptr<DH> dh (new DH);
return 0;
}
The problem is basically that in the State Pattern, state transitions are made by
invoking the the ChangeState method in the Context class, which invokes the
constructor of the next state.
Because of the circular dependency, I can't invoke the constructor because it's
not possible to pre-define both of the constructors of the 'problem' states.
I had a look at this article, and the template method which seemed to be the ideal solution - but it doesn't compile and my knowledge of templates is a rather limited...
The other idea I had is to try and introduce a Helper class to the subclassed states,
via multiple inheritance, to see if it's possible to specify the base class's constructor
and have a reference to the state subclasse's constructor. But I think that was rather
ambitious...
Finally, would a direct implmentation of the Factory Method Design Pattern be the best way
to resolve the entire problem?
You can define the member functions outside of the class definitions, e.g.,
class DL : public State
{
public:
void Trigger2();
};
inline void DL::Trigger2() { new DH(); }
Define the member functions that rely on later class definitions after those classes are defined. The inline keyword is only necessary if you define the member function outside of the class in the header file.
As an aside, why are you just using new DH() in your functions; you're leaking memory everywhere!