I need some help with inheritance and coding to interfaces in C++. I'm creating a state machine from which I'll derive another state machine. Therefore I have two interacting parts, a StateMachine and a State. The problem is that with this design, I cannot derive a specialised State from either the StateMachine or a DerivedStateMachine.
class StateMachine; //fwd
class State {
public:
virtual void action(StateMachine *engine) = 0;
virtual ~State() = default;
};
class StateMachine {
public:
StateMachine() = default;
explicit StateMachine(State &state) : state_(&state) {};
virtual void setState(State &state) {
state_ = &state;
}
[[nodiscard]] virtual State *getState() const {
return state_;
}
protected:
State *state_ = nullptr;
};
class DerivedStateMachine : public StateMachine {
public:
using StateMachine::StateMachine;
int doSpecializedThings(){
return special_thing_;
}
void setSpecialState(int specialState) {
special_thing_ = specialState;
}
private:
int special_thing_;
};
The issue with DerivedStateDependsOnGeneralStateMachine is that a StateMachine* doesn't have access to the doSpecializedThings() method.
class DerivedStateDependsOnGeneralStateMachine : public State {
virtual void action(StateMachine *engine) {
int important_value = engine->doSpecializedThings();
};
};
And the problem with DerivedStateDependsOnDerivedStateMachine is that you can't override a method with different arguments to the parent.
class DerivedStateDependsOnDerivedStateMachine : public State {
void action(DerivedStateMachine *engine) override {
engine->doSpecializedThings();
};
};
Can anybody see a way out of this knot I've tied myself in? Clearly I've messed up the design somewhere. What's 'normal' (for want of a better word) in such situations?
edits
To address the comments, firstly @Ted Lyngmo I am using the state machine design that I found in this post. It is odd that the mutual dependency is built into the design but its deliberate. The StateMachine needs to hold a reference to a State at all times and the State is responsible for determining the next state. The next state might depend on variables stored in the StateMachine so its useful to have a reference to the StateMachine in the State.
To get a little more concrete, I'm writing a Poker game. The idea is to have an abstract StateMachine interface from which I can derive a PokerEngine state machine, which conforms to the interface. I also thought I should have an abstract State, from which I can derive a PokerState. This would all work without the abstract level, and might initially be easier to think about, but its important for me to practice coding to interfaces to enable dependency injection and mocking. The irony is that in trying to do these things I've violated the Liskov substitution principle. Anyway, the PokerEngine will need to do things like getPotAmount which is a specialized method that I wouldn't want to any StateMachine.