The notion of a container as an object which contains other objects is introduced in Section . Conspicuous by their absence from the interface are member functions for putting objects into the container and for taking objects out of the container. As it turns out, the particular forms of the functions required depend on the type of container implemented. Therefore, we have left the specification of those functions for the classes which are derived from the Container base class.
Another reason for leaving these matters unspecified, is that we have not yet defined what it means for one object to be contained within another! We have two options:
The main advantage of using direct containment is its simplicity. It is easy to understand and easy to implement. However, it does suffer some problems. First, if the objects which are to be put into a container are large, i.e., if they occupy a large amount of memory space, the copying of the objects is likely to be both time-consuming and space-consuming. Second, an object cannot be contained in more than one container at a time. Third, a container cannot contain itself.
The indirect containment approach addresses these three concerns. By keeping a pointer to the contained object rather than a copy of the contained object, it is not necessary to copy the object when it is put into the container--this saves time and space. By keeping pointers to the contained objects, it is possible to put a pointer to the same object into several different containers. Finally, it is possible to put the pointer to a container into the container itself.
The indirect containment approach is not without disadvantages. The principal disadvantage being that for every access to a contained object it is necessary to dereference a pointer. This adds a constant overhead to such accesses. Despite the disadvantages, the Container classes presented in the following chapters are all implemented using indirect containment.