Using Type-safe Generic Lists In Templates
Go Up to Class Templates Overview Index
In general, when you need to write lots of nearly identical things, consider using templates. The problems with the following class definition, a generic list class,
class GList { public: void insert( void * ); void *peek(); . . . };
are that it isn't type-safe and common solutions need repeated class definitions. Since there's no type checking on what gets inserted, you have no way of knowing what results you'll get. You can solve the type-safe problem by writing a wrapper class:
class FooList : public GList { public: void insert( Foo *f ) { GList::insert( f ); } Foo *peek() { return (Foo *)GList::peek(); } . . . };
This is type-safe. insert will only take arguments of type pointer-to-Foo or object-derived-from-Foo, so the underlying container will only hold pointers that in fact point to something of type Foo. This means that the cast in FooList::peek() is always safe, and you've created a true FooList. Now, to do the same thing for a BarList, a BazList, and so on, you need repeated separate class definitions. To solve the problem of repeated class definitions and type-safety, you can once again use templates. See the example for type-safe generic list class. The C++ Standard Template Library (STL) has a rich set of type-safe collection classes.
By using templates, you can create whatever type-safe lists you want, as needed, with a simple declaration. And there's no code generated by the type conversions from each wrapper class so there's no runtime overhead imposed by this type safety.