Looking for a better way to integrate a static list into a set of classes
- by EvilTeach
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.