【发布时间】:2015-04-09 23:55:51
【问题描述】:
我正在尝试为我的游戏创建一个状态管理器,我有 4 个类:
游戏状态:
// foward declaration to avoid circular-referency
class StateManager;
class GameState
{
public:
virtual ~GameState() { }
virtual void update(StateManager* gameManager) = 0;
virtual void draw(StateManager* gameManager) = 0;
protected:
GameState() { }
};
状态管理器:
class StateManager
{
public:
StateManager();
virtual ~StateManager();
void addState(GameState* gameState);
void update(StateManager* stateManager);
void draw(StateManager* stateManager);
protected:
// store states in a unique_ptr to avoid memory leak
std::vector<std::unique_ptr<GameState> > states_;
};
游戏:
class Game : public StateManager
{
public:
void compute()
{
// call methos of statemanager
update(this);
draw(this);
}
}
主菜单:
class MainMenu : public GameState
{
public:
// override the pure virtual methos of GameState
void update(StateManager* stateManager)
{
// problem here.
// I need to handle instance of Game in this class,
// but the pointer is one StateManager
}
void draw(StateManager* stateManager) {}
}
当我像这样初始化我的游戏时:game.addState(new MainMenu())。
我可以访问MainMenu 中的类Game 的唯一方法是强制转换指针?
// MainMenu class
void update(StateManager* stateManager)
{
Game* game = (Game*) stateManager;
game.input.getKey(ANY_KEY);
//...
}
这是对的吗?有些东西告诉我我做错了。
【问题讨论】:
-
“某事告诉我我做错了。”那是什么?
-
每个人都想要多态性的所有好处与具体类的所有好处相结合,这很混乱。您需要将
dynamic_cast您的StateManager*转换为Game*。失败时返回nullptr。 -
StateManager::update和StateManager::draw将两个StateManager对象作为输入 - 这有意义吗?我会将addState更改为void addState(std::unique_ptr<GameState>);以明确它需要所有权。 -
没有必要,在我的代码中它们不存在。
game.addState(new Level ())不是比这更好吗:std::unique_ptr <gamestate> state(new Level ()); game.addState (state);?? -
为什么
StateManagerupdate和draw还要把StateManager*作为参数呢?而且您在那里使用的是普通指针,因此很难说这些方法背后的意图是什么。共享所有权、传递、回调?通常向下铸造表示设计问题/缺陷。你保证对象是Derived类型吗?如果是这样,您为什么将其传递为Base。如果不是,为什么不呢?为什么在你真正需要的时候允许自己“丢失”(你丢失静态的)类型信息。
标签: c++ inheritance