For example:
class DistanceBase { public: virtual ~DistanceBase() {} virtual double distance(const RD_Vector&) = 0; virtual DistanceBase* clone() const = 0; virtual void load(RD_Bfstream&) =0; virtual void save(RD_Bfstream&) const =0; virtual const string& isA() const =0; private: static string classname_; // To record name of class };
Implementation for L1Distance:
// Declare and define the string to hold the class name string DistanceBase::classname_ = string("DistanceBase"); short L1Distance::versionNo() const { return 1; } const string& L1Distance::isA() const { return classname_; } void L1Distance::save(RD_Bfstream& bfs) const { bfs<<isA(); bfs<<versionNo(); // No other data }
void L1Distance::load(RD_Bfstream& bfs) { string name; bfs>>name; if (name!=isA()) { cerr<<"L1Distance::load() Unable to load "; cerr<<name<<" into L1Distance object."<<endl; abort(); } short v; bfs>>v; switch (v) { case (1): // No other data break; default: cerr<<"Unexpected version number "<<v<<endl; abort(); } }
In addition, we need the following associated functions in the base class:
RD_Bfstream& operator<<( RD_Bfstream& bfs, const BaseClass* b) { if (b) b->save(bfs); else bfs << RD_NULL_PTR; return bfs; } RD_Bfstream& operator<<( RD_Bfstream& bfs, const BaseClass& b) { b.save(bfs); return bfs; } RD_Bfstream& operator>>( RD_Bfstream& bfs, BaseClass& b) { b.load(bfs); return bfs; }