How to choose between some methods at runtime?
In order to make my code a bit clearer, I was trying to split a long piece of code into several methods (a little PHP-like).
I have a variable CurrentStep
indicating the current screen to be rendered.
class Game
{
private:
enum Step { Welcome = 0, Menu, };
unsigned int CurrentStep;
}
Now I want to call the corresponding method 开发者_运维技巧when rendering the frame:
void Game::RenderFrame
{
switch (CurrentStep)
{
case Welcome:
// the actual work is done by WelcomeScreen() to keep this clean
WelcomeScreen(); break;
case Menu:
// same here
MenuScreen(); break;
}
}
I hope it is understandable what I was trying to achieve. Eventually it is supposed to call the appropriate method (at runtime).
However, this way is just that redundant... Isn't there a "better" way to go with C++?
I guess what you are looking for is the command pattern.
Read this detailed explanation (for C++)
http://www.dreamincode.net/forums/topic/38412-the-command-pattern-c/
to learn more about it.
First off, your private variable should be declared as Step CurrentStep;
and RenderFrame()
needs parentheses. Next, it's hard to give specific advice given how general and vague the question is, but in principle you could do something with inheritance:
class AbstractGameState
{
virtual ~AbstractGameState() { }
virtual void renderFrame() = 0;
};
class WelcomeScreenState : public AbstractGameState
{
void renderFrame(); // implement!
};
class MenuState : public AbstractGameState
{
void renderFrame(); // implement!
};
class Game
{
std::vector<std::shared_ptr<AbstractGameState> > gameStates;
public:
void renderFrame()
{
std::shared_ptr<AbstractGameState> state = getCurrentState(); // implement!
state->renderFrame();
}
};
We're going to need more information. If you make RenderFrame a virtual function, you can use run-time polymorphism to call the correct case of RenderFrame.
Besides the polymorphic approach that Kerrek posted (some would call it the classic object-oriented approach), there are other techniques that doesn't use polymorphism.
One of them are table driven methods
the other one worth mentioned is the visitor pattern, already efficiently implemented in the boost variant library. Here is an example that shows something similar to what you want to do
How many other states will you have?
Do the implementations of WelcomeScreen()
and MenuScreen()
have anything in common that can be moved into a common base class?
If the answer to the first question is "a few others" or the answer to the second is "not much" then your code is just fine. Keep things simple if you can.
Inheritance, the Command Pattern and other approaches that are suggested will complicate your code a bit while allowing more flexibility in adding more states in the future. You know your app better and know what its future holds.
精彩评论