Domanda

My game's main loop looks like this:

std::vector<std::unique_ptr<State>> states;

for(size_t i = 0; i < states.size(); i++)
{
     states[i]->Update();
     states[i]->Draw();

}

Their is a flaw with this though. I can't modify the vector (delete a state) during the iteration because if I deleted the current state the iteration is on then it breaks obviously because there is no state to call update and draw on. So I thought it would be a good idea to make a vector of states that should be added to the states vector and make a vector of states that should be deleted to the states vector. Then after the loop is over modify the states vector and no problems will occur mid iteration.

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

I can't delete states from the states vector though, an error is thrown on the statesToBeRemoved.clear() line and I think it's because when I call the states.erase(...) line it deletes the element from the states vector which consequently nullifies the same element in the statesToBeRemoved vector since that element points to an object that no longer exists.

You can't just delete a std::unique_ptr without destroying what the pointer points to so I don't think there is a way to delete the element from the states vector without nullifying the element in the statesToBeRemoved vector. So how do solve this problem?

Thanks.

È stato utile?

Soluzione

Different pointer types cater for different ownership semantics:

  • unique_ptrs are for unique ownership, this is why your current code does not work
  • shared_ptrs are for shared ownership - when the last shared_ptr managing an object goes out of scope, it is destroyed
  • raw pointers (*) don't really say anything about the semantics they are modeling, but you have to enforce all constraints manually - that's what makes them dangerous. They are however, safe, (and in my opinion the sensible choice) for pointers that do never have ownership of the object pointed to.

So: Your statesToBeAdded is safe as long as you can guarantee that you never have anything in there that isn't already in states. statesToBeRemoved is different: The objects are already there and in states, and it would make sense to have states take ownership of the objects - hence raw pointers would be a fair choice for statesToBeRemoved.

Note that all this is based on the few lines of code you have shown, depending on the circumstances it may well be that it makes sense to store States instead of unique_ptr<State>s in your states, etc ...

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top