Example Two Revisited
It is worth looking at the second example again so that you can see the mechanisms used to implement polymorphic persistence. The expression:
 
istr >> collection2;
calls the overloaded extraction operator:
 
RWvistream& operator>>(RWvistream& str, RWCollectable& obj);
This extraction operator has been written to call the object’s restoreGuts() virtual function. In this case the object, obj, is an ordered collection and its version of restoreGuts() has been written to repeatedly call:
 
RWvistream& operator>>(RWvistream&, RWCollectable*&);
once for each member of the collection. Actually, the Smalltalk collection classes are so similar that they all share the same version of restoreGuts(). Note that its second argument is a reference to a pointer, not just a reference. This version of the overloaded operator>> looks at the stream, figures out the kind of object on the stream, allocates an object of that type off the heap, restores it from the stream, and finally returns a pointer to it. If this operator>> encounters a reference to a previous object, it just returns the old address. These pointers are inserted into the collection by the ordered collection's restoreGuts().
These details about the polymorphic persistence mechanism are particularly important when you design your own polymorphically persistable class, as described in Designing an RWCollectable Class. And when working with such classes, note that when Smalltalk-like collection classes are restored, the type of the restored objects is never known. Hence, the restoring processes must always allocate those objects off the heap. This means that you are responsible for deleting the restored contents. An example of this occurs at the end of both polymorphic persistence examples.