SourcePro Core : Essential Tools Module User's Guide : Persistence : A Few Friendly Warnings : Don't Save Distinct Objects with the Same Address
Don't Save Distinct Objects with the Same Address
You must be careful not to isomorphically save distinct objects that may have the same address. The internal tables that are used in isomorphic and polymorphic persistence use the address of an object to determine whether or not an object has already been saved.
The following example assumes that all the work has been done to make Godzilla and Mothra isomorphically persistable:
 
class Mothra {/* ... */};
RW_DEFINE_PERSISTABLE(Mothra)
struct Godzilla {
Mothra mothra_;
int wins_;
};
RW_DEFINE_PERSISTABLE(Godzilla)
/* ... */
Godzilla godzilla;
/* ... */
stream << godzilla;
/* ... */
stream >> godzilla; // The restore may be garbled!
When godzilla is saved, the address of godzilla will be saved in an isomorphic save table. The next item to be saved is godzilla.mothra_. Its address is saved in the same internal save table.
The problem is that on some compilers godzilla and godzilla.mothra_ have the same address! Upon restoration of godzilla, godzilla.mothra_ is streamed out as a value, and godzilla is streamed out as a reference to godzilla.mothra_. If godzilla and godzilla.mothra have the same address, the restore of godzilla fails because the extraction operator attempts to initialize godzilla with the contents of godzilla.mothra_.
There are two ways to overcome this difficulty. The first is to structure your class so that simple data members, such as int, precede data members that are isomorphically persistent. Using this method, class Godzilla looks like this:
 
struct Godzilla {
int wins_;
Mothra mothra_; // mothra_ now has a different address.
};
If Godzilla is structured as shown here, mothra_ is displaced from the front of godzilla and can't be confused with godzilla. The variable wins_, of type int, is saved with simple persistence and is not stored in the isomorphic save table.
The second approach to solving the problem of identical addresses between a class and its members is to insert an isomorphically persistable member as a pointer rather than a value. For Godzilla this would look like:
 
struct Godzilla {
Mothra* mothraPtr_;// mothraPtr_ points to a different address.
int wins_;
};
In this second approach, mothraPtr_ points to a different address than godzilla, so confusion is once again avoided.