好的:我对C++和静态语言都很陌生.来自多年的红宝石(和其他动态语言),我不知道这是否可能.
我一直在制作游戏状态系统......好吧游戏.我希望系统能够让我轻松剪切并粘贴到其他游戏中,而无需进行任何(或极少数)更改.
我想要改进的两件事是状态切换的方式以及状态指针的保存方式.
可能存在任意数量的状态,但在内存中始终存在至少2到3个状态.
丑陋的1号.
目前我有一个状态管理器类,里面有这样的东西:
void StateManager::changeState(StateID nextStateID)
{
// UNFOCUS THE CURRENT STATE //
if (currentState())
{
currentState()->onUnFocus();
// DESTROY THE STATE IF IT WANTS IT //
if(currentState()->isDestroyedOnUnFocus()) {
destroyCurrentState();
}
}
if (m_GameStates[nextStateID]) {
// SWITCH TO NEXT STATE //
setCurrentState(nextStateID);
}
else
{
// CREATE NEW STATE //
switch (nextStateID)
{
case MainMenuStateID:
m_GameStates[MainMenuStateID] = new MainMenuState;
break;
case GameStateID:
m_GameStates[MainMenuStateID] = new GameStates;
break;
};
setCurrentState(nextStateID);
}
// FOCUS NEXT STATE //
currentState()->onFocus();
}
Run Code Online (Sandbox Code Playgroud)
这种方法有效,但我觉得它不是很好.
是否可以传递一种类型?然后打电话给新的吗?
new NextGameState; // Whatever type that may be.
Run Code Online (Sandbox Code Playgroud)
poloymophism可以帮助吗?所有国家都来自a class State
.
丑陋的2号.
我认为需要改进的另一件事是我存储状态的方式.
State* m_GameStates[MaxNumberOfStates];
Run Code Online (Sandbox Code Playgroud)
所有状态都初始化为NULL,因此我可以测试状态是否存在,如果不存在则在需要时创建状态.
它可以正常工作,因为我可以调用当前状态:
m_GameStates[m_CurrentState];
Run Code Online (Sandbox Code Playgroud)
但是,我不喜欢这个有两个原因.当任何时候只有2或3个指针处于活动状态时,如果有一个充满NULL指针的数组,那似乎有点浪费.[编者注:第二个原因是什么?]
我vector_ptr
想把它变成一个,但没有,因为它会产生额外的复杂性,检查是否存在状态.矢量似乎强化了Ugance No 1.因为我需要有一个列表来检查每个州.
任何建议或方向表示赞赏.
谢谢,菲尔.
对于你的第一个问题,是的,你可以传递一个类型,但有一些警告。
我在您的问题下添加了评论,要求提供更多信息。在我们明白这一点之前,我真的无法说出应该如何完成,但请阅读模板。
您可以创建一个可以传递类型的函数模板,例如如下所示:
template <typename T>
void Foo() {
T* x = new T();
...
}
Foo<int>() // call Foo with the type T set to 'int'
Run Code Online (Sandbox Code Playgroud)
这样做有一些限制,因为必须在编译时指定类型,但它是一个非常强大的语言功能。
MainState
另一种选择可能会更好,因为您似乎在变量 ( ) 和类型 ( )之间存在关联MainMenu
,它可能是使用特征类。再说一遍,我不确定在你的情况下具体是如何完成的,因为我们还没有看到该函数的全部内容(特别是 是什么类型MainState
,以及它是如何/何时创建的?)
也可能通过多态性来解决问题,但同样,我需要查看更多的上下文来提出解决方案。
对于第二个问题,您可以使用标准库map
:
#include <map>
// I'm not sure what type m_CurrentState is, so use its type instead of KeyType below
std::map<KeyType, State*> m_GameStates;
// and to perform a lookup in the map:
GameStates[m_CurrentState];
Run Code Online (Sandbox Code Playgroud)
最后,一个非常非常重要的建议:
停止到处使用指针。停止调用new
创建新对象。作为一般规则,对象应该在堆栈上创建(而不是Foo* f = new Foo;
,只需执行Foo f;
您通常只想复制对象本身,而不是使用指针。或者,创建引用而不是指针。
当你确实需要使用动态内存分配时,你仍然不应该new
直接使用。相反,创建一个包装对象,该对象在其构造函数中内部分配所需的内容new
,并在析构函数中再次释放它。
如果你正确地做到了这一点,它几乎可以解决内存管理的所有令人头疼的问题。
通用技术称为RAII。
归档时间: |
|
查看次数: |
4140 次 |
最近记录: |