Основной цикл моей игры выглядит так:
std::vector<std::unique_ptr<State>> states;
for(size_t i = 0; i < states.size(); i++)
{
states[i]->Update();
states[i]->Draw();
}
Их недостаток с этим все же. Я не могу изменить вектор (удалить состояние) во время итерации, потому что, если я удалил текущее состояние, в котором итерация включена, то он, очевидно, нарушается, потому что нет состояния, чтобы вызвать обновление и рисовать. Поэтому я подумал, что было бы неплохо создать вектор состояний, который следует добавить к states
вектор и сделать вектор состояний, которые должны быть удалены в states
вектор. Затем, после окончания цикла, измените states
вектор и никаких проблем не произойдет в середине итерации.
std::vector<std::unique_ptr<State>> states;
std::vector<std::unique_ptr<State>> statesToBeAdded;
std::vector<std::unique_ptr<State>> statesToBeRemoved;
for(size_t i = 0; i < states.size(); i++)
{
states[i]->Update();
states[i]->Draw();
}
for(size_t i = 0; i < statesToBeAdded.size(); i++)
{
states.push_back(std::move(statesToBeAdded[i]));
}
statesToBeAdded.clear();
for(size_t i = 0; i < statesToBeRemoved.size(); i++)
{
states.erase(std::remove(states.begin(), states.end(), statesToBeRemoved[i]), states.end());
}
statesToBeRemoved.clear(); //error is thrown here
Я не могу удалить состояния из states
вектор, однако, ошибка генерируется на statesToBeRemoved.clear()
линия, и я думаю, что это потому, что когда я звоню states.erase(...)
строка удаляет элемент из states
вектор, который, следовательно, обнуляет тот же элемент в statesToBeRemoved
вектор, так как этот элемент указывает на объект, который больше не существует.
Вы не можете просто удалить std :: unique_ptr, не разрушив то, на что указывает указатель, поэтому я не думаю, что есть способ удалить элемент из states
вектор без обнуления элемента в statesToBeRemoved
вектор. Так как же решить эту проблему?
Благодарю.
Различные типы указателей учитывают различную семантику владения:
unique_ptr
s для уникального владельца, поэтому ваш текущий код не работаетshared_ptr
s для совместного владения — когда последний shared_ptr
управление объектом выходит из области видимости, оно уничтожается*
) на самом деле ничего не говорите о семантике, которую они моделируют, но вы должны применять все ограничения вручную — это делает их опасными. Однако они безопасны (и, на мой взгляд, разумный выбор) для указателей, которые никогда не владеют указанным объектом.Так что ваши statesToBeAdded
безопасно, если вы можете гарантировать, что у вас никогда не будет ничего там, что еще не states
, statesToBeRemoved
отличается: объекты уже есть и в states
и имело бы смысл иметь states
взять на себя ответственность за объекты — следовательно, сырые указатели будут справедливым выбором для statesToBeRemoved
,
Обратите внимание, что все это основано на нескольких строчках кода, которые вы показали, в зависимости от обстоятельств вполне возможно, что имеет смысл хранить State
с вместо unique_ptr<State>
в вашем states
, так далее …
Других решений пока нет …