I'm trying to expand my sons interest from Warcraft 3 programming into C++ to broaden his horizons to a degree. We are planning on porting a little game that he wrote.
The context goes something like this.
- There are Ships and Missiles, for which Ships will use Missiles and interact with them
- A Container exists which will hold 'a list' of ships.
- A Container exists which will hold 'a list' of planets.
- One can apply a function over all elements in the Container (for_each)
- Ships and Missles can be created/destroyed at any time
- New objects automatically insert themselves into the proper container.
I cobbled a small example together to do that job, so we can talk about topics (list, templates etc) but I am not pleased with the results.
#include <iostream>
#include <list>
using namespace std;
/* Base class to hold static list in common with various object groups */
template<class T>
class ObjectManager
{
public :
ObjectManager(void)
{
cout << "Construct ObjectManager at " << this << endl;
objectList.push_back(this);
}
virtual ~ObjectManager(void)
{
cout << "Destroy ObjectManager at " << this << endl;
}
void for_each(void (*function)(T *))
{
for (objectListIter = objectList.begin();
objectListIter != objectList.end();
++objectListIter)
{
(*function)((T *) *objectListIter);
}
}
list<ObjectManager<T> *>::iterator objectListIter;
static list<ObjectManager<T> *> objectList;
};
/* initializer for static list */
template<class T>
list<ObjectManager<T> *> ObjectManager<T>::objectList;
/* A simple ship for testing */
class Ship : public ObjectManager<Ship>
{
public :
Ship(void) : ObjectManager<Ship>()
{
cout << "Construct Ship at " << this << endl;
}
~Ship(void)
{
cout << "Destroy Ship at " << this << endl;
}
friend ostream &operator<<(ostream &out,const Ship &that)
{
out << "I am a ship";
return out;
}
};
/* A simple missile for testing */
class Missile : public ObjectManager<Missile>
{
public :
Missile(void) : ObjectManager<Missile>()
{
cout << "Construct Missile at " << this << endl;
}
~Missile(void)
{
cout << "Destroy Missile at " << this << endl;
}
friend ostream &operator<<(ostream &out,const Missile &that)
{
out << "I am a missile";
return out;
}
};
/* A function suitable for the for_each function */
template <class T>
void show(T *it)
{
cout << "Show: " << *it << " at " << it << endl;
}
int main(void)
{
/* Create dummy planets for testing */
Missile p1;
Missile p2;
/* Demonstrate Iterator */
p1.for_each(show);
/* Create dummy ships for testing */
Ship s1;
Ship s2;
Ship s3;
/* Demonstrate Iterator */
s1.for_each(show);
return 0;
}
Specifically, The list is effectively embedded in each ship though the inheritance mechanism. One must have a ship, in order to access the list of ships. One must have a missile in order to be able to access the list of missiles. That feels awkward.
My question boils down to "Is there a better way to do this?"
- Automatic object container creation
- Automatic object insertion
- Container access without requiring an object in the list to access it.
I am looking for better ideas. All helpful entries get an upvote.
Thanks
Evil.