#ifndef POINTER_H #define POINTER_H #include "RefCount.h" #ifndef NULL #define NULL 0 #endif #ifdef NULL_POINTER #undef NULL_POINTER #endif #define NULL_POINTER (static_cast (NULL)) #define Obj(P) (*P) // NOTE: // 1) The class used to replace T in the template below must be derived from RefCount // 2) The object that Pointer "points to" must be dynamically allocated template class Pointer { public: enum Exceptions {NullPointerException}; Pointer (); explicit Pointer (T *); explicit Pointer (const Pointer &); virtual ~Pointer (); bool DoesNotExist () const; bool Exists () const; Pointer & New (); Pointer & New (const T &); T & ObjectOf (); const T & ObjectOf () const; Pointer & PointsTo (const Pointer &); Pointer & SetTo (const Pointer &); void SetToNull (); T & operator * (); const T & operator * () const; T* operator -> (); const T* operator -> () const; Pointer & operator = (const Pointer &); bool operator == (const Pointer &); bool operator ! () const; bool operator != (const Pointer &); operator bool () const; private: Pointer & Copy (const Pointer &); void Decrement (); void SetAndIncrement (const T *); Pointer & SetTo (const T *); Pointer & operator = (const T *); T * Ptr; }; template Pointer ::Pointer ():Ptr (NULL_POINTER) { } template Pointer ::Pointer (T * p) { SetAndIncrement (p); } template Pointer ::Pointer (const Pointer & P) { SetAndIncrement (P.Ptr); } template Pointer ::~Pointer () { Decrement (); } template inline bool Pointer::DoesNotExist () const { return Ptr == NULL_POINTER; } template inline bool Pointer::Exists () const { return Ptr != NULL_POINTER; } template inline Pointer & Pointer::New () { Decrement (); SetAndIncrement (new T); return *this; } template inline Pointer & Pointer::New (const T & t) { Decrement (); SetAndIncrement (new T (t)); return *this; } template inline T & Pointer::ObjectOf () { if (Ptr) return *Ptr; else throw NullPointerException; } template inline const T & Pointer::ObjectOf () const { if (Ptr) return *Ptr; else throw NullPointerException; } template inline Pointer & Pointer::PointsTo (const Pointer & P) { return Copy (P); } template inline Pointer & Pointer::SetTo (const Pointer & P) { return SetTo (P.Ptr); } template inline void Pointer::SetToNull () { SetTo (NULL_POINTER); } template inline T & Pointer::operator * () { return ObjectOf (); } template inline const T & Pointer::operator * () const { return ObjectOf (); } template inline T * Pointer::operator -> () { if (Ptr) return Ptr; else throw NullPointerException; } template inline const T * Pointer::operator -> () const { if (Ptr) return Ptr; else throw NullPointerException; } template inline Pointer & Pointer::operator = (const Pointer & P) { if (this != &P) SetTo (P.Ptr); else; return *this; } template inline bool Pointer::operator == (const Pointer & P) { return Ptr == P.Ptr; } template inline bool Pointer::operator ! () const { return DoesNotExist (); } template inline bool Pointer::operator != (const Pointer & P) { return Ptr != P.Ptr; } template inline Pointer::operator bool () const { return Exists (); } template inline Pointer & Pointer::Copy (const Pointer & P) { return *this = P; } template inline void Pointer::Decrement () { if (Ptr) (*Ptr).DownCount (); else; } template inline void Pointer::SetAndIncrement (const T * p) { if ((Ptr = (T *) (p)) != NULL_POINTER) (*Ptr).UpCount (); else; } template inline Pointer & Pointer::SetTo (const T * p) { Decrement (); SetAndIncrement (p); return *this; } template inline Pointer & Pointer::operator = (const T * p) { return SetTo (p); } #endif