这是我的通用C ++游戏循环:
std::vector<std::unique_ptr<State>> states;
while(window.isOpen())
{
//event checking and other stuff
for(size_t i = 0; i < states.size(); i++)
{
states[i]->Update();
//clear backbuffer
states[i]->Draw(window);
//draw backbuffer
}
}
问题在于,每当我从states
列表中删除状态时,程序就会崩溃。我猜这是因为一旦状态被删除,你就不能再使用该对象,因为它显然不再存在了。
我很确定解决此问题的最佳方法是将states
向量中的状态复制到新的状态,然后对states
向量进行任何更改将在循环期间进行更改。
所以这就是我想出来的:
std::vector<std::unique_ptr<State>> states;
std::vector<State> tempStates;
while(window.isOpen())
{
//event checking and other stuff
for(size_t i = 0; i < states.size(); i++)
{
tempStates.push_back(*states[i]);
}
for(size_t i = 0; i < tempStates.size(); i++)
{
tempStates[i].Update();
//clear backbuffer
tempStates[i].Draw(window);
//draw backbuffer
}
tempStates.clear();
}
但是,在构建文件error C2259: 'State' : cannot instantiate abstract class
中xmemory0
的应用程序后,我收到错误消息。 “State”是我的其他状态继承的抽象基类。我不明白为什么我得到这个错误,因为我没有实例化那个抽象类,我正在实例化一个继承它的类。 states
没有充满State
个对象,它充满了从它继承的对象,我想它会以某种方式使它充满State
个对象,但无论我是不是在实例化它们
那么为什么我会收到此错误以及如何解决?
感谢。
修改的
这基本上是在使用上述第一种方法时如何删除states
内的元素。这是一个继承自State
:
void Update()
{
if(/*whatever*/)
{
StateManager::RemoveState(std::unique_ptr<State>(this));
//call stack comes back here but cant because this no longer exists
}
}
StateManager.cpp
void StateManager::RemoveState(std::unique_ptr<State> state)
{
states.erase(std::remove(states.begin(), states.end(), state), states.end());
}
答案 0 :(得分:2)
传输您要删除的元素可能很简单:
std::vector<unique_ptr<state>> states;
while ( /* stuff */)
{
std::vector<unique_ptr<state>> temp;
for (std::size_t i = 0; i != states.size(); ++i)
{
if ( /* move? */)
{
temp.push_back(std::move(states[i]));
}
}
for (std::size_t i = 0; i != temp.size(); ++i)
{
// process temp[i]
}
}
删除的元素将是每个循环体末尾的states
向量中的空指针,因此您可能希望修剪它们:
states.erase(std::remove(states.begin(), states.end(), nullptr), states.end());
(目前没有任何std::copy_if
和std::move_if
算法,但一旦将它们添加到标准库中,此代码将变得更短。)