Sign in to follow this  
Crazyfool

Vectors and pointers

Recommended Posts

Crazyfool    307
Howdy folks, I am currently using an std::vector to store Player pointers where Player is a class representing, you guessed it, the players. So it looks like this:
std::vector<Player*> subscribers;
Now, what I am trying to do is iterate through the list and compare if I should remove them from the list. I first initially decided to use iterators since they are faster and the built in mechanic for iterating through a std::container. Then I ran into some problems, I couldn't access the data within the actual vector because iterators were treated as pointers. I usually would use something like:
someIteratorForSomeVector->memberFunction();
But since it is an iterator to a pointer, I am not sure how to do this. (As a side note, I used simple integer iteration, but I need to remove the elements at times, thus requiring erase() which takes an iterator.)

Share this post


Link to post
Share on other sites
SiCrane    11839
Incidently, you can erase elements from a vector when using integer iteration. An index can be converted into an iterator by adding it to the begin() iterator. So if you have a vector v and want to erase the nth element you can use v.erase(v.begin() + n).

Share this post


Link to post
Share on other sites
Zahlman    1682
1) Why are you storing pointers to Players, instead of just Player objects directly?

2) The standard library provides functionality for removing things from containers:


#include <algorithm>
#include <vector>

// Somewhere, we have:
std::vector<Player*> myplayers;

// Somewhere else:

bool shouldRemove(Player* p) {
// code goes here that describes whether a player should be removed from
// the container.
}

// Then, when the time comes:
std::erase(std::remove_if(myplayers.begin(), myplayers.end(), shouldRemove))


But that will NOT attempt to call delete or delete[] on any of the Player*'s. If you want to keep things easy for yourself, your tools have to be adequate for your design. Sometimes that means the best answer is to simplify your design; other times, it means using more advanced tools (such as boost::shared_ptr).

3) Iterators are designed so that you can use them like pointers are used. So using an iterator to a pointer is like using a pointer to a pointer: to get at the ultimately-pointed at thing, you simply dereference twice: either (**foo).x or (*foo)->x (since the arrow operator performs one dereference).

4)
Quote:
(As a side note, I used simple integer iteration, but I need to remove the elements at times, thus requiring erase() which takes an iterator.)


You may find your life is easier if you try to separate the logic that "updates" elements from the logic which "removes" them.

Share this post


Link to post
Share on other sites
ViperG    206
agree'd

if you store them as pointers, then you must do garbage clean up...

if you store them directly, no garbage cleanup.

and there is no real advantage to storing them as pointers, unless you are doing inserts into your vector causing re-indexing, pointers would be faster than say structs.

but you should avoid inserts, and if you have to, pushback then swap with something.

you also can loop through your vector with just a simple for loop.

for (unsigned int loop=0; loop < myvect.size(); loop++)
{
myvect[loop]->mystruct/whatever
if (myvect[loop]->mystruct.remove==true])
{
myvect.erase(myvect.begin.()+loop);
loop--;
}
}

erasing also causes re-indexing of the vector, you can stop this by simply, swaping the element you want to erase with the last element in the vector, then erase that one, if your order in the vector is not important.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this