#ifndef __abstract_field #define __abstract_field #include 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