Automatically Adding New Class Instances to a Container

Problem

You need to store all instances of a class in a single container without requiring the users of the class to do anything special.

Solution

Include in the class a static member that is a container, such as a list, defined in . Add an object's address to the container at construction and remove it upon destruction. Example 8-4 shows how.

Example 8-4. Keeping track of objects

#include 
#include 
#include 

using namespace std;

class MyClass {
protected:
 int value_;
public:
 static list instances_;
 MyClass(int val);
 ~MyClass( );
 static void showList( );
};

list MyClass::instances_;

MyClass::MyClass(int val) {
 instances_.push_back(this);
 value_ = val;
}

MyClass::~MyClass( ) {
 list::iterator p =
 find(instances_.begin( ), instances_.end( ), this);
 if (p != instances_.end( ))
 instances_.erase(p);
}

void MyClass::showList( ) {
 for (list::iterator p = instances_.begin( );
 p != instances_.end( ); ++p)
 cout << (*p)->value_ << endl;
}

int main( ) {
 MyClass a(1);
 MyClass b(10);
 MyClass c(100);
 MyClass::showList( );
}

Example 8-4 will create output like this:

1
10
100

 

Discussion

The approach in Example 8-4 is straightforward: use a static list to hold pointers to objects. When an object is created, add its address to the list; when it's destroyed, remove it. There are a couple of things to remember.

As with any static data member, you have to declare it in the class header and define it in an implementation file. Example 8-4 is all in one file, so it doesn't apply here, but remember that you should define the static variable in an implementation file, not a header. See Recipe 8.5 for an explanation of why.

You don't have to use a static member. You can, of course, use a global object, but then the design is not self-contained. Furthermore, you have to allocate the global object somewhere else, pass it in to MyClass at construction, and, in general, do a bit more bookkeeping.

Be aware that the shared use of a global container like Example 8-4 will not work if multiple threads are instantiating objects of MyClass. You need to serialize access to the shared object through mutexes; see Chapter 12 for recipes relating to this and other multithreading techniques.

If you want to keep track of all instances of a class, you may also want to use a Factory pattern. Essentially, this approach would mean that clients call a function to get a new object instead of using the new operator. See Recipe 8.2 for more details on how to do this.

See Also

Recipe 8.2

Building C++ Applications

Code Organization

Numbers

Strings and Text

Dates and Times

Managing Data with Containers

Algorithms

Classes

Exceptions and Safety

Streams and Files

Science and Mathematics

Multithreading

Internationalization

XML

Miscellaneous

Index



C++ Cookbook
Secure Programming Cookbook for C and C++: Recipes for Cryptography, Authentication, Input Validation & More
ISBN: 0596003943
EAN: 2147483647
Year: 2006
Pages: 241

Flylib.com © 2008-2020.
If you may any questions please contact us: flylib@qtcs.net