next up previous
Next: RD_LoaderSingleton<T> Up: C++ Design For Research Previous: Default constructors

Loading/Saving by Base-Class Pointer

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



 

Tim Cootes
2/24/1998