Main Page   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   File Members  

panda/src/express/pointerTo.h

Go to the documentation of this file.
00001 // Filename: pointerTo.h
00002 // Created by:  drose (23Oct98)
00003 //
00004 ////////////////////////////////////////////////////////////////////
00005 //
00006 // PANDA 3D SOFTWARE
00007 // Copyright (c) 2001, Disney Enterprises, Inc.  All rights reserved
00008 //
00009 // All use of this software is subject to the terms of the Panda 3d
00010 // Software license.  You should have received a copy of this license
00011 // along with this source code; you will also find a current copy of
00012 // the license at http://www.panda3d.org/license.txt .
00013 //
00014 // To contact the maintainers of this program write to
00015 // panda3d@yahoogroups.com .
00016 //
00017 ////////////////////////////////////////////////////////////////////
00018 
00019 #ifndef POINTERTO_H
00020 #define POINTERTO_H
00021 
00022 ////////////////////////////////////////////////////////////////////
00023 //
00024 // This file defines the classes PointerTo and ConstPointerTo (and
00025 // their abbreviations, PT and CPT).  These should be used in place of
00026 // traditional C-style pointers wherever implicit reference counting
00027 // is desired.
00028 //
00029 // The syntax is:                     instead of:
00030 //
00031 //    PointerTo<MyClass> p;            MyClass *p;
00032 //    PT(MyClass) p;
00033 //
00034 //    ConstPointerTo<MyClass> p;       const MyClass *p;
00035 //    CPT(MyClass) p;
00036 //
00037 // PointerTo and ConstPointerTo will automatically increment the
00038 // object's reference count while the pointer is kept.  When the
00039 // PointerTo object is reassigned or goes out of scope, the reference
00040 // count is automatically decremented.  If the reference count reaches
00041 // zero, the object is freed.
00042 //
00043 // Note that const PointerTo<MyClass> is different from
00044 // ConstPointerTo<MyClass>.  A const PointerTo may not reassign its
00045 // pointer, but it may still modify the contents at that address.  On
00046 // the other hand, a ConstPointerTo may reassign its pointer at will,
00047 // but may not modify the contents.  It is like the difference between
00048 // (MyClass * const) and (const MyClass *).
00049 //
00050 // In order to use PointerTo, it is necessary that the thing pointed
00051 // to--MyClass in the above example--either inherits from
00052 // ReferenceCount, or is a proxy built with RefCountProxy or
00053 // RefCountObj (see referenceCount.h).  However, also see
00054 // PointerToArray, which does not have this restriction.
00055 //
00056 // It is crucial that the PointerTo object is only used to refer to
00057 // objects allocated from the free store, for which delete is a
00058 // sensible thing to do.  If you assign a PointerTo to an automatic
00059 // variable (allocated from the stack, for instance), bad things will
00060 // certainly happen when the reference count reaches zero and it tries
00061 // to delete it.
00062 //
00063 // It's also important to remember that, as always, a virtual
00064 // destructor is required if you plan to support polymorphism.  That
00065 // is, if you define a PointerTo to some base type, and assign to it
00066 // instances of a class derived from that base class, the base class
00067 // must have a virtual destructor in order to properly destruct the
00068 // derived object when it is deleted.
00069 //
00070 ////////////////////////////////////////////////////////////////////
00071 
00072 #include <pandabase.h>
00073 
00074 #include "referenceCount.h"
00075 #include "typedef.h"
00076 #include "memoryUsage.h"
00077 #include "config_express.h"
00078 
00079 
00080 ////////////////////////////////////////////////////////////////////
00081 //       Class : PointerToBase
00082 // Description : This is the base class for PointerTo and
00083 //               ConstPointerTo.  Don't try to use it directly; use
00084 //               either derived class instead.
00085 ////////////////////////////////////////////////////////////////////
00086 template <class T>
00087 class PointerToBase {
00088 public:
00089   typedef T To;
00090 
00091 protected:
00092   INLINE PointerToBase(To *ptr);
00093   INLINE PointerToBase(const PointerToBase<T> &copy);
00094   INLINE ~PointerToBase();
00095 
00096   void reassign(To *ptr);
00097 
00098   INLINE void reassign(const PointerToBase<To> &copy);
00099 
00100   To *_ptr;
00101 
00102   // No assignment or retrieval functions are declared in
00103   // PointerToBase, because we will have to specialize on const
00104   // vs. non-const later.
00105 
00106 public:
00107   // These comparison functions are common to all things PointerTo, so
00108   // they're defined up here.
00109 #ifndef CPPPARSER
00110 #ifndef WIN32_VC
00111   INLINE bool operator == (const To *other) const;
00112   INLINE bool operator != (const To *other) const;
00113   INLINE bool operator > (const To *other) const;
00114   INLINE bool operator <= (const To *other) const;
00115   INLINE bool operator >= (const To *other) const;
00116   INLINE bool operator == (To *other) const;
00117   INLINE bool operator != (To *other) const;
00118   INLINE bool operator > (To *other) const;
00119   INLINE bool operator <= (To *other) const;
00120   INLINE bool operator >= (To *other) const;
00121 
00122   INLINE bool operator == (const PointerToBase<To> &other) const;
00123   INLINE bool operator != (const PointerToBase<To> &other) const;
00124   INLINE bool operator > (const PointerToBase<To> &other) const;
00125   INLINE bool operator <= (const PointerToBase<To> &other) const;
00126   INLINE bool operator >= (const PointerToBase<To> &other) const;
00127 #endif  // WIN32_VC
00128   INLINE bool operator < (const To *other) const;
00129   INLINE bool operator < (const PointerToBase<To> &other) const;
00130 #endif  // CPPPARSER
00131 
00132 PUBLISHED:
00133   INLINE bool is_null() const;
00134   INLINE void clear();
00135 
00136   void output(ostream &out) const;
00137 };
00138 
00139 template<class T>
00140 INLINE ostream &operator <<(ostream &out, const PointerToBase<T> &pointer) {
00141   pointer.output(out);
00142   return out;
00143 }
00144 
00145 ////////////////////////////////////////////////////////////////////
00146 //       Class : PointerTo
00147 // Description : PointerTo is a template class which implements a
00148 //               smart pointer to an object derived from
00149 //               ReferenceCount.
00150 ////////////////////////////////////////////////////////////////////
00151 template <class T>
00152 class PointerTo : public PointerToBase<T> {
00153 public:
00154   typedef TYPENAME PointerToBase<T>::To To;
00155 PUBLISHED:
00156   INLINE PointerTo(To *ptr = (To *)NULL);
00157   INLINE PointerTo(const PointerTo<T> &copy);
00158 
00159 public:
00160   INLINE To &operator *() const;
00161   INLINE To *operator -> () const;
00162   INLINE operator TYPENAME PointerToBase<T>::To *() const;
00163 
00164 PUBLISHED:
00165   // When downcasting to a derived class from a PointerTo<BaseClass>,
00166   // C++ would normally require you to cast twice: once to an actual
00167   // BaseClass pointer, and then again to your desired pointer.  You
00168   // can use the handy function p() to avoid this first cast and make
00169   // your code look a bit cleaner.
00170 
00171   // e.g. instead of (MyType *)(BaseClass *)ptr, use (MyType *)ptr.p()
00172 
00173   // If your base class is a derivative of TypedObject, you might want
00174   // to use the DCAST macro defined in typedObject.h instead,
00175   // e.g. DCAST(MyType, ptr).  This provides a clean downcast that
00176   // doesn't require .p() or any double-casting, and it can be
00177   // run-time checked for correctness.
00178   INLINE To *p() const;
00179 
00180   INLINE PointerTo<T> &operator = (To *ptr);
00181   INLINE PointerTo<T> &operator = (const PointerTo<T> &copy);
00182 
00183   // These functions normally wouldn't need to be redefined here, but
00184   // we do so anyway just to help out interrogate (which doesn't seem
00185   // to want to automatically export the PointerToBase class).  When
00186   // this works again in interrogate, we can remove these.
00187   INLINE bool is_null() const { return PointerToBase<T>::is_null(); }
00188   INLINE void clear() { PointerToBase<T>::clear(); }
00189 };
00190 
00191 
00192 ////////////////////////////////////////////////////////////////////
00193 //       Class : ConstPointerTo
00194 // Description : A ConstPointerTo is similar to a PointerTo, except it
00195 //               keeps a const pointer to the thing.
00196 //
00197 //               (Actually, it keeps a non-const pointer, because it
00198 //               must be allowed to adjust the reference counts, and
00199 //               it must be able to delete it when the reference count
00200 //               goes to zero.  But it presents only a const pointer
00201 //               to the outside world.)
00202 //
00203 //               Notice that a PointerTo may be assigned to a
00204 //               ConstPointerTo, but a ConstPointerTo may not be
00205 //               assigned to a PointerTo.
00206 ////////////////////////////////////////////////////////////////////
00207 template <class T>
00208 class ConstPointerTo : public PointerToBase<T> {
00209 public:
00210   typedef TYPENAME PointerToBase<T>::To To;
00211 PUBLISHED:
00212   INLINE ConstPointerTo(const To *ptr = (const To *)NULL);
00213   INLINE ConstPointerTo(const PointerTo<T> &copy);
00214   INLINE ConstPointerTo(const ConstPointerTo<T> &copy);
00215 
00216 public:
00217   INLINE const To &operator *() const;
00218   INLINE const To *operator -> () const;
00219   INLINE operator const TYPENAME PointerToBase<T>::To *() const;
00220 
00221 PUBLISHED:
00222   INLINE const To *p() const;
00223 
00224   INLINE ConstPointerTo<T> &operator = (const To *ptr);
00225   INLINE ConstPointerTo<T> &operator = (const ConstPointerTo<T> &copy);
00226   INLINE ConstPointerTo<T> &operator = (const PointerTo<T> &copy);
00227 
00228   // These functions normally wouldn't need to be redefined here, but
00229   // we do so anyway just to help out interrogate (which doesn't seem
00230   // to want to automatically export the PointerToBase class).  When
00231   // this works again in interrogate, we can remove these.
00232   INLINE bool is_null() const { return PointerToBase<T>::is_null(); }
00233   INLINE void clear() { PointerToBase<T>::clear(); }
00234 };
00235 
00236 
00237 // Finally, we'll define a couple of handy abbreviations to save on
00238 // all that wasted typing time.
00239 
00240 #define PT(type) PointerTo< type >
00241 #define CPT(type) ConstPointerTo< type >
00242 
00243 #include "pointerTo.I"
00244 
00245 #endif

Generated on Fri May 2 00:38:30 2003 for Panda by doxygen1.3