My iterator hell

Started by
5 comments, last by MaulingMonkey 18 years, 10 months ago
This post is a follow up to my post "My vector hell", where some kind people achieved the impossible and helped me learn how to create a vector of pointers to Actors, Actors being the character objects in my game. As you can see, my World class, which is a sort of manager for everything in my game world, has a vector of pointers to Actors:

class World
{
private:
	//objects
	std::vector<Actor*> Actors;
//etc
}

I know how to create new Actors and store pointers to them in the vector too:

for ( int actor=0 ; actor<8 ; actor++ )
{
	Actor* newActor = new Actor();
	Actors.push_back( newActor );
}


I think I've done it right, it certainly seems to work! But how do I loop through the Actors, to call their member functions? Let's say the Actor class has a member function Paint() that draws the Actor to the screen. How do I get each Actor to Paint itself? Presumably I have to use an Iterator? I want to avoid smart pointers at this stage, I want to learn how to use normal pointers then maybe think about the smart stuff another day! Any help vastly appreciated.
Advertisement
unless I'm missing something:

vector&lt;Actor*&gt;::iterator i;for (i=Actors.begin();i!=actors.end();i++){    (*i)-&gt;Paint();}


you might want to check the pointers are valid too.

Edit: worth noting that as vectors are Sequences you can also use the random access operator and do it like this:

for (unsigned int count=0;count<Actors.size();count++){  Actors[count]->Paint();}
[size="1"]
There are twenty billion different ways to paint each actor in a vector [lol].

Here's the main ones that come to mind:

//Method 1: Basic loop using indexfor ( int actor = 0 ; actor < Actors.size() ; ++actor ) {    Actors[ actor ]->Paint();}//Method 2: Basic loop using iteratorsfor ( std::vector< Actor * >::iterator actor = Actors.begin() ; actor != Actors.end() ; ++actor ) {    (*actor)->Paint();}//Method 3: std::for_each with std::mem_fun:std::for_each( Actors.begin() , Actors.end() , std::mem_fun( &Actor::Paint ) );


[Edited by - MaulingMonkey on June 21, 2005 3:16:33 PM]
The first one is as easy as vector pie. I like it!

How come you don't need iterators? I guess you need iterators for more complex things like deleting one from the middle.

OK, so is there a simple way I can just get at one of them?

Let's say I only want to get the third one in a list of ten actors to paint itself. Obviously if they were stored in an array it's something simple like this:

Actors[2].Paint();

Is there a simple way to do this with them stored in this vector of pointers?

Actors[2]->Paint();
Vector pie!

Thanks!


Quote:Original post by darenking
The first one is as easy as vector pie. I like it!

How come you don't need iterators?


Iterators are designed to just look like fancy pointers, and vectors to look like fancy arrays. You could do this:

const char array[] = "I like pie oh yes I do";const char * begin = array;const char * end = array + size_of( array ); //note: my own size_of function, not the operator sizeof, although here they're interchangeablefor ( const char * i = begin ; i != end ; ++i ) {    putchar( *i );}

Which is the same concept as this:
std::vector< char > array = ...;std::vector< char >::iterator begin = array.begin();std::vector< char >::iterator end = array.end();for ( std::vector< char >::iterator i = begin ; i != end ; ++i ) {    putchar( *i );}

Similarly, one could do this:
const char array[] = "I like pie oh yes I do";for ( int i = 0 ; i < size_of( array ) ; ++i ) {     putchar( array );}

Or for the same effect, this:
std::vector< char > array = ...;for ( int i = 0 ; i < array.size() ; ++i ) {     putchar( array );}


Quote:I guess you need iterators for more complex things like deleting one from the middle.


Yes and no. If I wanted to remove the third element of a vector, I could do:

my_vector.erase( my_vector.begin() + 2 );

(since .begin() + 0 is the same as .begin() which is the first element). I say yes and no because yes, this example uses iterators - but no, because you never actually have a named iterator variable :-).

This topic is closed to new replies.

Advertisement