From: John D. G. <jd...@di...> - 2005-04-26 19:57:11
|
Erik Vos wrote: > I'm from a school of thought that classes should be self-managing, > which is why I tend to include static arrays and methods to manage > the instances of a class inside that class, as I have done in Player. It's not exactly clear to me what you mean by self-managing. Part of my coding philosophy is that, when taking any action that needs to be cleaned up afterward (opening a file, allocating heap memory, etc.), that action should be represented by a class object with a destructor that cleans it up when it goes out of scope. That way you can't forget it. But if you mean you want to have a class keep a list of all objects of that class, that's easy enough to do without static arrays. Here's an example in C++ of a class that maintains a circular linked list of every instance of itself. class Example; // to allow pointer declarations class Example { private: Example *prev, *next; static Example *first; public: Example(); ~Example(); // whatever other members it will contain }; Example *Example::first = 0; // The only static member. Initialize once. Example::Example() { // If there are any other constructors, they also must contain this code. if (first) { // Insert the new instance into the circular pointer chain at the // end (just before *first). Notice that first does not change. next = first; prev = next->prev; prev->next = this; next->prev = this; } else { // We're creating the first instance. For now, prev, next, and // first will all point to that one instance. prev = this; next = this; first = this; } } Example::~Example() { if (prev == this) { // We're deleting the last instance. first = 0; } else { // Unlink this instance from the pointer chain. prev->next = next; next->prev = prev; // If we're deleting *first, update first. if (first == this) first = next; } } Of course, in a multi-threaded program, both this constructor and destructor would need locking calls added around their present contents. |