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

show all menu



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

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