|
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.
|