Introduction
My C++ programming background comes from DOS Borland C++. In their latest DOS
version 3.1, they included a template library for collections. It was a great
piece of work. When I started to use Visual C++ v2.2, I even tried to use Borland's
collection template library within Visual C++ but with no success. The only
other solution was to switch to Microsoft's collections that are part of the
MFC. However, this was always a problem for the following reasons:
- It is not easy to switch from one container type to another once the application
is written (from list to array for example).
- Iterators are different for different type of containers.
- If one is writting a DLL, service or a console application and needs containers,
the solution is to either dynamically or statically link MFC which makes the
project dependent on MFC.
Recently, I started using STL and it is great. The beginning was a bit difficult
but once I grasped the idea, it was easy. This article contains some first hand
experiences with STL and is intended for programmers that want to use STL fast
and without going into greater details.
Rule 1:
You can create STL containers that store either objects or pointer to objects.
class TMyClass;
typedef list<TMyClass> TMyClassList;
typedef list<TMyClass*> TMyClassPtrList;
Usually, list container that stores the object is used. However, if the object
is using a machine resource (handle to file, named pipe, socket or similar),
then it is more appropriate to use lists that stores pointers to objects.
If the container stores objects, then it is automatically cleaned up during
container destruction. However, if it stores pointers to objects, programmer
is responsible to delete all pointers.
Rule 2:
Each class (whose instance will go into the container) must implement at least
the copy constructor (it is good to implement also the assignment operator.
class TMyClass {
private:
...
public:
TMyClass(..);
TMyClass(const TMyClass& obj) { *this = obj; }
TMyClass& operator=(const TMyClass& obj);
...
};
This is necessary since the STL will create a local copy of the object when
you insert an object instance into the container. If you do not write a correct
code for the copy constructor, object within a list will have some data members
uninitialized.
Rule 3:
Inserting an object into the container is done in the following way:
TMyClass object;
TMyClassList myList;
TMyClassList::iterator it;
it = myList.insert(myList.end(), object);
TMyClass *pObject = &(*it);
Previous example shows how to insert an object into the container and obtain
a pointer to the object within container. This is necessary since the container
will create a new copy of the "object" instance and the original "object"
instance is not used any more. In case you are storing pointers to a list, this
is not necessary since original pointer is stored into the container.
Rule 4:
Iterating through container is done in the following way:
TMyClassList::iterator it;
TMyClass *pObject;
for (it = myList.begin(); it != myList.end(); it ++) {
pObject = &(*it);
}
However, if you are storing pointers into the container, then the previous
code fragment has to be modified to the following:
TMyClassList::iterator it;
TMyClass *pObject;
for (it = myList.begin(); it != myList.end(); it ++) {
pObject = *it;
}
Rule 5:
Removing items from the container is done in the following way:
TMyClassList::iterator it;
TMyClass *pObject;
for (it = myList.begin(); it != myList.end(); it ++) {
pObject = &(*it);
if (pObject satisfies some delete criteria) then
myList.erase(it);
delete pObject;
}
Additional line to delete the pointer to the object is needed since the container
will not delete a stored pointer so it has to be manually deleted.
Conclusion
The only thing that is missing from STL is a function similar to CString::Format()
function.
I hope that this article will give you enough information to start using STL.
You will be surprised how easy it is.