2
0

pointerTo.h 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223
  1. // Filename: pointerTo.h
  2. // Created by: drose (23Oct98)
  3. //
  4. ////////////////////////////////////////////////////////////////////
  5. #ifndef POINTERTO_H
  6. #define POINTERTO_H
  7. ////////////////////////////////////////////////////////////////////
  8. //
  9. // This file defines the classes PointerTo and ConstPointerTo (and
  10. // their abbreviations, PT and CPT). These should be used in place of
  11. // traditional C-style pointers wherever implicit reference counting
  12. // is desired.
  13. //
  14. // The syntax is: instead of:
  15. //
  16. // PointerTo<MyClass> p; MyClass *p;
  17. // PT(MyClass) p;
  18. //
  19. // ConstPointerTo<MyClass> p; const MyClass *p;
  20. // CPT(MyClass) p;
  21. //
  22. // PointerTo and ConstPointerTo will automatically increment the
  23. // object's reference count while the pointer is kept. When the
  24. // PointerTo object is reassigned or goes out of scope, the reference
  25. // count is automatically decremented. If the reference count reaches
  26. // zero, the object is freed.
  27. //
  28. // Note that const PointerTo<MyClass> is different from
  29. // ConstPointerTo<MyClass>. A const PointerTo may not reassign its
  30. // pointer, but it may still modify the contents at that address. On
  31. // the other hand, a ConstPointerTo may reassign its pointer at will,
  32. // but may not modify the contents. It is like the difference between
  33. // (MyClass * const) and (const MyClass *).
  34. //
  35. // In order to use PointerTo, it is necessary that the thing pointed
  36. // to--MyClass in the above example--either inherits from
  37. // ReferenceCount, or is a proxy built with RefCountProxy or
  38. // RefCountObj (see referenceCount.h). However, also see
  39. // PointerToArray, which does not have this restriction.
  40. //
  41. // It is crucial that the PointerTo object is only used to refer to
  42. // objects allocated from the free store, for which delete is a
  43. // sensible thing to do. If you assign a PointerTo to an automatic
  44. // variable (allocated from the stack, for instance), bad things will
  45. // certainly happen when the reference count reaches zero and it tries
  46. // to delete it.
  47. //
  48. // It's also important to remember that, as always, a virtual
  49. // destructor is required if you plan to support polymorphism. That
  50. // is, if you define a PointerTo to some base type, and assign to it
  51. // instances of a class derived from that base class, the base class
  52. // must have a virtual destructor in order to properly destruct the
  53. // derived object when it is deleted.
  54. //
  55. ////////////////////////////////////////////////////////////////////
  56. #include <pandabase.h>
  57. #include "referenceCount.h"
  58. #include "typedef.h"
  59. #include "memoryUsage.h"
  60. #include "config_express.h"
  61. ////////////////////////////////////////////////////////////////////
  62. // Class : PointerToBase
  63. // Description : This is the base class for PointerTo and
  64. // ConstPointerTo. Don't try to use it directly; use
  65. // either derived class instead.
  66. ////////////////////////////////////////////////////////////////////
  67. template <class T>
  68. class PointerToBase {
  69. public:
  70. typedef T To;
  71. protected:
  72. INLINE PointerToBase(To *ptr);
  73. INLINE PointerToBase(const PointerToBase<T> &copy);
  74. INLINE ~PointerToBase();
  75. void reassign(To *ptr);
  76. INLINE void reassign(const PointerToBase<To> &copy);
  77. To *_ptr;
  78. // No assignment or retrieval functions are declared in
  79. // PointerToBase, because we will have to specialize on const
  80. // vs. non-const later.
  81. public:
  82. // These comparison functions are common to all things PointerTo, so
  83. // they're defined up here.
  84. #ifndef CPPPARSER
  85. #ifndef WIN32_VC
  86. INLINE bool operator == (const To *other) const;
  87. INLINE bool operator != (const To *other) const;
  88. INLINE bool operator > (const To *other) const;
  89. INLINE bool operator <= (const To *other) const;
  90. INLINE bool operator >= (const To *other) const;
  91. INLINE bool operator == (const PointerToBase<To> &other) const;
  92. INLINE bool operator != (const PointerToBase<To> &other) const;
  93. INLINE bool operator > (const PointerToBase<To> &other) const;
  94. INLINE bool operator <= (const PointerToBase<To> &other) const;
  95. INLINE bool operator >= (const PointerToBase<To> &other) const;
  96. #endif // WIN32_VC
  97. INLINE bool operator < (const To *other) const;
  98. INLINE bool operator < (const PointerToBase<To> &other) const;
  99. #endif // CPPPARSER
  100. PUBLISHED:
  101. INLINE bool is_null() const;
  102. INLINE void clear();
  103. void output(ostream &out) const;
  104. };
  105. template<class T>
  106. INLINE ostream &operator <<(ostream &out, const PointerToBase<T> &pointer) {
  107. pointer.output(out);
  108. return out;
  109. }
  110. ////////////////////////////////////////////////////////////////////
  111. // Class : PointerTo
  112. // Description : PointerTo is a template class which implements a
  113. // smart pointer to an object derived from
  114. // ReferenceCount.
  115. ////////////////////////////////////////////////////////////////////
  116. template <class T>
  117. class PointerTo : public PointerToBase<T> {
  118. PUBLISHED:
  119. INLINE PointerTo(To *ptr = (To *)NULL);
  120. INLINE PointerTo(const PointerTo<T> &copy);
  121. public:
  122. INLINE To &operator *() const;
  123. INLINE To *operator -> () const;
  124. INLINE operator PointerToBase<T>::To *() const;
  125. PUBLISHED:
  126. // When downcasting to a derived class from a PointerTo<BaseClass>,
  127. // C++ would normally require you to cast twice: once to an actual
  128. // BaseClass pointer, and then again to your desired pointer. You
  129. // can use the handy function p() to avoid this first cast and make
  130. // your code look a bit cleaner.
  131. // e.g. instead of (MyType *)(BaseClass *)ptr, use (MyType *)ptr.p()
  132. // If your base class is a derivative of TypedObject, you might want
  133. // to use the DCAST macro defined in typedObject.h instead,
  134. // e.g. DCAST(MyType, ptr). This provides a clean downcast that
  135. // doesn't require .p() or any double-casting, and it can be
  136. // run-time checked for correctness.
  137. INLINE To *p() const;
  138. INLINE PointerTo<T> &operator = (To *ptr);
  139. INLINE PointerTo<T> &operator = (const PointerTo<T> &copy);
  140. // These functions normally wouldn't need to be redefined here, but
  141. // we do so anyway just to help out interrogate (which doesn't seem
  142. // to want to automatically export the PointerToBase class). When
  143. // this works again in interrogate, we can remove these.
  144. INLINE bool is_null() const { return PointerToBase<T>::is_null(); }
  145. INLINE void clear() { PointerToBase<T>::clear(); }
  146. };
  147. ////////////////////////////////////////////////////////////////////
  148. // Class : ConstPointerTo
  149. // Description : A ConstPointerTo is similar to a PointerTo, except it
  150. // keeps a const pointer to the thing.
  151. //
  152. // (Actually, it keeps a non-const pointer, because it
  153. // must be allowed to adjust the reference counts, and
  154. // it must be able to delete it when the reference count
  155. // goes to zero. But it presents only a const pointer
  156. // to the outside world.)
  157. //
  158. // Notice that a PointerTo may be assigned to a
  159. // ConstPointerTo, but a ConstPointerTo may not be
  160. // assigned to a PointerTo.
  161. ////////////////////////////////////////////////////////////////////
  162. template <class T>
  163. class ConstPointerTo : public PointerToBase<T> {
  164. PUBLISHED:
  165. INLINE ConstPointerTo(const To *ptr = (const To *)NULL);
  166. INLINE ConstPointerTo(const PointerTo<T> &copy);
  167. INLINE ConstPointerTo(const ConstPointerTo<T> &copy);
  168. public:
  169. INLINE const To &operator *() const;
  170. INLINE const To *operator -> () const;
  171. INLINE operator const PointerToBase<T>::To *() const;
  172. PUBLISHED:
  173. INLINE const To *p() const;
  174. INLINE ConstPointerTo<T> &operator = (const To *ptr);
  175. INLINE ConstPointerTo<T> &operator = (const ConstPointerTo<T> &copy);
  176. INLINE ConstPointerTo<T> &operator = (const PointerTo<T> &copy);
  177. // These functions normally wouldn't need to be redefined here, but
  178. // we do so anyway just to help out interrogate (which doesn't seem
  179. // to want to automatically export the PointerToBase class). When
  180. // this works again in interrogate, we can remove these.
  181. INLINE bool is_null() const { return PointerToBase<T>::is_null(); }
  182. INLINE void clear() { PointerToBase<T>::clear(); }
  183. };
  184. // Finally, we'll define a couple of handy abbreviations to save on
  185. // all that wasted typing time.
  186. #define PT(type) PointerTo< type >
  187. #define CPT(type) ConstPointerTo< type >
  188. #include "pointerTo.I"
  189. #endif