This is just an example of course. In reality, I have states like FlySpellState, with the function flies(), which also seems to have no place in Person (since people cannot fly normally), though it could be.
Sure. So what you want is a bunch of different states. These states can all be changed when diffent situations apply.
struct Action
{
virtual void doAction() {std::cout << "Nothing Happens\n";}
};
class Person
{
std::map<std::string, std::unique_ptr<Action>> actionMap;
Action& getAction(std::string const& action)
{
static Action defaultAction; // Will do Nothing by default.
auto find = actionMap.find(action);
return find == actionMap.end()
? defaultAction
: **find;
}
void sing()
{
getAction("sing").doAction();
}
void fly()
{
getAction("fly").doAction(); // Default do nothing unless you have read the scroll of flying
}
void drink()
{
actionMap["sing"].reset(new Drunk);
actionMap["walk"].reset(new Stumble);
actionMap["talk"].reset(new Slur);
}
void readScrollOfFlying()
{
actionMap["fly"].reset(new FlySpellState);
}
};
Rather than using std::unique_ptr
and lots of calls to new
. You may want to look up the flyweight pattern
.