Click on abstract_field.h to get source.
#ifndef __abstract_field
#define __abstract_field
#include <iostream>
class field_base; // forward declare
class abstract_field {
field_base* elem_ptr;
public:
// arithmetic
inline bool operator==(const abstract_field& af) const;
inline bool operator!=(const abstract_field& af) const {return !operator==(af);}
inline abstract_field& operator+(const abstract_field& af) const;
inline abstract_field& operator-(const abstract_field&) const;
inline abstract_field& operator*(const abstract_field&) const;
inline abstract_field& operator/(const abstract_field&) const;
// object management
abstract_field();
abstract_field(const abstract_field& af);
abstract_field(int i);
abstract_field& operator=(const abstract_field& af);
~abstract_field();
// Input/Output
friend ostream& operator<<(ostream&, const abstract_field&);
friend istream& operator>>(istream&, abstract_field&);
}; // end class abstract_field
class field_base {// actual fields are derived from this class
// and must implement all virtual members
static field_base* default_elem_ptr;
// the static member is needed in abstract_field::abstract_field(int)
// and in operator>>(istream&, abstract_field&)
// the following access default_elem_ptr:
friend void set_default_elem_ptr(field_base*);
// initializes default_elem_ptr (see below)
friend istream& operator>>(istream&, abstract_field&);
friend class abstract_field;
public:
// arithmetic
virtual bool operator==(const field_base&) const = 0;
virtual field_base& operator+(const field_base&) const = 0;
virtual field_base& operator-(const field_base&) const = 0;
virtual field_base& operator*(const field_base&) const = 0;
virtual field_base& operator/(const field_base&) const = 0;
// object management: there are no constructors
// this class should only be used in tandem with abstract_field
virtual field_base* clone() const = 0;
virtual field_base* make_int(int) = 0;
virtual field_base& operator=(const field_base&) = 0;
virtual ~field_base() {}
// Input/Output
virtual void print(ostream&) const = 0;
virtual void read(istream&) = 0;
}; // end class field_base
// Implementation for abstract_field members
inline bool abstract_field::operator==(const abstract_field& af) const
{return (*elem_ptr) == (*af.elem_ptr); }
inline abstract_field& abstract_field::operator+(const abstract_field& af) const
{abstract_field* af_ptr = new abstract_field();
af_ptr->elem_ptr = &((*elem_ptr) + (*af.elem_ptr));
return *af_ptr;
}
abstract_field::abstract_field()
{// guard against assigning to and reading into variables
// that are constructed by default: elem_ptr will be deleted
elem_ptr = 0; // delete 0 does nothing
}
abstract_field::abstract_field(const abstract_field& af)
{elem_ptr = af.elem_ptr->clone(); }
abstract_field::abstract_field(int i)
{elem_ptr = field_base::default_elem_ptr->make_int(i); }
abstract_field& abstract_field::operator=(const abstract_field& af)
{if(this != &af)
{delete elem_ptr;
elem_ptr = af.elem_ptr->clone();
}
return *this;
}
abstract_field::~abstract_field()
{delete elem_ptr; }
ostream& operator<<(ostream& os, const abstract_field& af)
{af.elem_ptr->print(os); return os;}
istream& operator>>(istream& is, abstract_field& af)
{field_base* fb_ptr;
fb_ptr = field_base::default_elem_ptr->clone();
fb_ptr->read(is);
delete af.elem_ptr;
af.elem_ptr = fb_ptr;
return is;
}
// Implementation for field_base
field_base* field_base::default_elem_ptr; // declare static member
void set_default_elem_ptr(field_base* p)
{field_base::default_elem_ptr = p;}
#endif