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;
}