MPQC
2.3.1
|
The state library provides means for objects to save and restore their state. Features include:
For objects of a class to be savable with this library the class must inherit SavableState which in turn inherits DescribedClass. SavableState must be inherited with the virtual qualifier. Also, a constructor taking a StateIn& argument and a save_data_state(StateOut&) member must be provided. If the class has virtual base classes other than SavableState, then a save_vbase_state(StateOut&) member must also be provided.
Here is a simple example of the specification of a client, C, of SavableState:
class C: virtual public SavableState { private: int i; public: C(StateIn&); void save_data_state(StateOut&); };
Here is the implementation for the above:
static ClassDesc C_cd(typeid(C),"C",1,"virtual public SavableState", 0, 0, create<C>); void C::save_data_state(StateOut&so) { so.put(i); } C::C(StateIn&si): SavableState(si) { si.get(i); }
Here is an example of the specification of C, where C nonvirtually inherits from another SavableState derivative:
class C: public B { private: int i; public: C(StateIn&); void save_data_state(StateOut&); };
Here is the implementation for the above:
static ClassDesc C_cd(typeid(C),"C",1,"public B", 0, 0, create<C>); void C::save_data_state(StateOut&so) { B::save_data_state(so); so.put(i); } C::C(StateIn&si): SavableState(si), B(si) { si.get(i); }
Note that B (or one of its parents) virtually inherits from SavableState, so the StateIn constructor for SavableState is called explicitly from the class C constructor.
Here is an example of the specification of C, where C nonvirtually inherits from another client of SavableState as well as virtually inherits from a client of SavableState:
class C: public B, virtual public E { private: int i; public: C(StateIn&); void save_vbase_state(StateOut&); void save_data_state(StateOut&); };
In this case a save_vbase_state member is required since virtual base classes besides SavableState exist. This member function must save the virtual base classes in the same order that virtual base classes are initialized in constructors. Virtual base classes are initialized before all other base classes in a depth first, left to right transversal of the directed acyclic graph of parent classes. In this example, B and E inherit virtually from SavableState. Here is the implementation:
static ClassDesc C_cd(typeid(C),"C",1,"public B, virtual public E", 0, 0, create<C>); void C::save_vbase_state(StateOut&sio) { SavableState::save_data_state(so); E::save_data_state(sio); } void C::save_data_state(StateOut&so) { B::save_parent_state(so); so.put(i); } C::C(StateIn&si): SavableState(si), B(si), E(si) { si.get(i); }
Here is an example where C has data members which are pointers to derivatives of SavableState:
class C: virtual public SavableState { private: A* ap; // A is also a SavableState public: C(StateIn&); void save_data_state(StateOut&); };
Here is the implementation for the above:
static ClassDesc C_cd(typeid(C),"C",1,"virtual public SavableState", 0, 0, create<C>); void C::save_data_state(StateOut&so) { SavableState::save_state(ap,so); } C::C(StateIn&si): SavableState(si) { ap = dynamic_cast<A>(SavableState::restore_state(si)); }
Here is an example where C has data members which are smart pointers to derivatives of SavableState:
class C: virtual public SavableState { private: Ref a; // A is also a SavableState public: C(StateIn&); void save_data_state(StateOut&); };
Here is the implementation for the above:
static ClassDesc C_cd(typeid(C),"C",1,"virtual public SavableState", 0, 0, create<C>); void C::save_data_state(StateOut&so) { SavableState::save_state(a.pointer(),so); } C::C(StateIn&si): SavableState(si) { a << SavableState::restore_state(so); }
Here is an example where C has data members which are pointers to data:
class C: virtual public SavableState { private: int vecsize; double *vec; int n1; int n2; double **array; public: C(StateIn&); void save_data_state(StateOut&); };
Here is the implementation for the above:
static ClassDesc C_cd(typeid(C),"C",1,"virtual public SavableState", 0, 0, create<C>); void C::save_data_state(StateOut&so) { so.put(vecsize); so.put_array_double(vec,vecsize);
so.put(n1); so.put(n2); for (int i=0; i<n1; i++) { so.put_array_double(array[i],n2); } } C::C(StateIn&si): SavableState(si) { si.get(vecsize); vec = new double[vecsize]; si.get_array_double(vec,vecsize);
si.get(n1); si.get(n2);
array = new double*[n1]; for (int i=0; i<n1; i++) { array[i] = new double[n2]; si.get_array_double(array[i],n2); } }