Jump to content
  • Advertisement
Sign in to follow this  
Beather

C++: Trouble looping over a list of objects (enemies, bullets, etc)

This topic is 3090 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hello, I do not know what is the correct technique in C++ to loop over a list of objects, where you have the possibility to perform tasks on every object in that list. Suppose I maintain a list of objects in my main class. vector<Object*> m_Objects; Now, I have Players, Enemies and Bullets in my game. Players, Enemies and Bullets inheret from Object. My question: How can I loop the list, and know what object I have? There is no "typeof" function or something similar which I can use. Something tricky I am doing at the moment, is to have a ClassName function for everyobject. For instance: virtual tstring ClassName () { return _T("Bullet"); } This however gets burdensome quickly. Is there another technique on looping every object in your scene and knowing what object is is efficiently? Thank you! Nick

Share this post


Link to post
Share on other sites
Advertisement
Quote:
Original post by Beather
Something tricky I am doing at the moment, is to have a ClassName function for everyobject. For instance:

virtual tstring ClassName () { return _T("Bullet"); }


It would be more efficient if you use:


virtual bool is_bullet();
virtual bool is_enemy();
virtual bool is_xyz();

Share this post


Link to post
Share on other sites
Something like this might be better.


typedef unsigned char ItemType;

class Object
{
public:
// ...
virtual ItemType getID() =0;
};



And every object that extends from this base class must define getID like follows:


class Bullet : public Object
{
public:
// ...
ItemType getID();
};

ItemType Bullet::getID()
{
static ItemType a = 0;
return a;
}

Share this post


Link to post
Share on other sites
It's easier to just use the type system already in C++. You could use typeid or try to dynamic_cast each pointer, if it fails it's not of that type. But why do you need to know the type? It's usually frowned upon.

Share this post


Link to post
Share on other sites
Usually you try to refactor the work into a virtual function in the base class that does the correct thing for each subtype. Can't think of a descriptive name for the operation? Maybe you inheritance heirarchy is poorly designed.

Instead of:

class Object { };

class A : public Object { };

class B : public Object { };

function frobnicate(list<Object *> objects)
{
foreach( Object * o in objects)
{
if(o is A)
{
// A stuff
}
else if(o is B)
{
// B stuff
}
}
}



Do this:

class Object {
public:
virtual void frobnicate() = 0;
};

class A : public Object {
virtual void frobnicate() {
// A stuff
}
};

class B : public Object {
virtual void frobnicate() {
// B stuff
}
};

function frobnicate(list<Object *> objects)
{
foreach( Object * o in objects)
{
o->frobnicate();
}
}


The advantage of this approach is that if you need to add a new derived class, you can implement all its behaviour in one place rather than looking through the code for any place you decided to do type switching. It is far less brittle, far more readable and idomatic, and probably a little faster too.

Another option is to use a visitor pattern.

Finally, and this might seem crazy, sometimes it is better to keep different objects in different containers, even if they share some base class. Having three different lists of objects with known concrete types can aid collision for example. It depends on how complex your game is.

Share this post


Link to post
Share on other sites
If all you have is Players, Enemies, Bullets the easiest and most efficient would probably be to store each type in a separate list.

Share this post


Link to post
Share on other sites
Quote:
Original post by pointer
It's easier to just use the type system already in C++. You could use typeid or try to dynamic_cast each pointer, if it fails it's not of that type. But why do you need to know the type? It's usually frowned upon.


Note that it is implementation defined what the result of type_info::name() looks like, e.g. one compiler could give you "_int32" for an integer, another one could give "i32", et cetera.

So if your code really makes assumptions upon type_info::name() (or similarly, typeid(your type).name()), it is doomed.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!