Ошибка не может создать абстрактный класс при создании экземпляра наследуемого класса

Это мой общий игровой цикл 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());
}

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 алгоритмы, но как только они будут добавлены в стандартную библиотеку, этот код станет намного короче.)

2

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]