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