9.1 How to Make a Type-Safe Collection

The Microsoft Foundation Class Library provides predefined type-safe collections that can be used to contain CObject, UINT, DWORD and CString elements. You can use these predefined collections (such as CObList) to hold collections of any objects derived from CObject. The Microsoft Foundation Class Library also provides other predefined collections to hold primitive types such as UINT and void pointers (void*). In general, however, it is often useful to define your own type-safe collections to hold objects of a more specific class and its derivatives.

There are three main ways to use collections with the Microsoft Foundation Class Library, as described by the following sections.

·To use predefined collections:

The easiest way to use the Microsoft Foundation collections is to use a predefined collection type, such as CWordArray. You can create a CWordArray and add UINT values to it and retrieve them. There is nothing more to do. You just use the predefined functionality.

You can also use a predefined collection, such as CObList, to hold objects that are derived from CObject. A CObList is defined to hold pointers to CObject. You can put any object that is derived from CObject into a CObList. When you retrieve an object from the list, you may have to cast the result to the proper type, since the CObList functions return pointers to CObject. For example, if you store CPerson objects in a CObList, you have to cast a retrieved element to be a pointer to a CPerson object. The following example uses a CObList to hold CPerson objects:

class CPerson : public CObject {...};

CPerson* p1 = new CPerson(...);

CObList myList;

myList.AddHead( p1 ); // no cast needed

CPerson* p2 = ( CPerson* )myList.GetHead();

This technique of using a predefined collection type and casting as necessary may be adequate for many of your collection needs. If you need further functionality or more type safety, read the next section.

·To derive and extend a collection:

You can also derive your own collection class from one of the predefined collection classes provided with the Microsoft Foundation Class Library. When you derive your class, you can add type-safe wrapper functions to provide a type-safe interface to existing functions.

For example, if you derived a list from CObList to hold CPerson objects, you might add the wrapper functions AddHeadPerson and GetHeadPerson, as shown below.

class CPersonList : public CObList

{

public:

void AddHeadPerson( CPerson* person )

{AddHead( person );}

CPerson* GetHeadPerson()

{return (CPerson*)GetHead();}

};

These wrapper functions provide a type-safe way to add and retrieve CPerson objects from the derived list. You can see that for the GetHeadPerson function, you are simply encapsulating the casting seen in the previous section.

You can also add new functionality by defining new functions that extend the capabilities of the collection rather than just wrapping existing functionality in type-safe wrappers. For example, a later section describes a function to delete all the objects contained in a list. This function could be added to the derived class as a member function.

·To use templates to create new collection classes:

The DOC directory (in your distribution disks) contains a technical note (TN004.TXT) that describes the Microsoft Foundation Class Library tool that you can use to create new type-safe collections from template files. These templates and tool allow you to create a version of an existing collection shape that is customized to hold a specified data type or object type.

The SAMPLE\TEMPLDEF directory (in your distribution disks) contains a sample program that expands templates defined using a subset of the proposed ANSI template syntax. The Foundation collection classes were generated with this program.