I'm just an inexperienced hobbyist and I'm still working on my approach but I myself go with stack based approach where top screen gets all controll over state manager, which mantains some shared instances(render window, font, pointer to itself) in a pack class, that gets passed to each state by reference in it's run() method. In main() I just instance my engine, put first state in it and then call mainRun() which is basically:
while(!mStack.empty())
{
cleanUp();//deletes states that got pop'd, it's delayed so I can still mess around with state internal variables after it got pop'd since it's not deleted yet
mStack.top()->run(mPack);
}
Game closing is just calling leaveBottom(0); which will pop all states, I used to call popTop(1000) to close game before writing that convinence leaveBottom method. I think that's alright approach, it decouples everything nicely. I can have 20 different game states, and 3 different eye-candy menu states, and mix and match menu to game as I please, without changing anything except the line in menu that does pack.Manager->pushTop(new GameState());