Panda3D
 All Classes Functions Variables Enumerations
pointerTo.h
1 // Filename: pointerTo.h
2 // Created by: drose (23Oct98)
3 //
4 ////////////////////////////////////////////////////////////////////
5 //
6 // PANDA 3D SOFTWARE
7 // Copyright (c) Carnegie Mellon University. All rights reserved.
8 //
9 // All use of this software is subject to the terms of the revised BSD
10 // license. You should have received a copy of this license along
11 // with this source code in a file named "LICENSE."
12 //
13 ////////////////////////////////////////////////////////////////////
14 
15 #ifndef POINTERTO_H
16 #define POINTERTO_H
17 
18 ////////////////////////////////////////////////////////////////////
19 //
20 // This file defines the classes PointerTo and ConstPointerTo (and
21 // their abbreviations, PT and CPT). These should be used in place of
22 // traditional C-style pointers wherever implicit reference counting
23 // is desired.
24 //
25 // The syntax is: instead of:
26 //
27 // PointerTo<MyClass> p; MyClass *p;
28 // PT(MyClass) p;
29 //
30 // ConstPointerTo<MyClass> p; const MyClass *p;
31 // CPT(MyClass) p;
32 //
33 // PointerTo and ConstPointerTo will automatically increment the
34 // object's reference count while the pointer is kept. When the
35 // PointerTo object is reassigned or goes out of scope, the reference
36 // count is automatically decremented. If the reference count reaches
37 // zero, the object is freed.
38 //
39 // Note that const PointerTo<MyClass> is different from
40 // ConstPointerTo<MyClass>. A const PointerTo may not reassign its
41 // pointer, but it may still modify the contents at that address. On
42 // the other hand, a ConstPointerTo may reassign its pointer at will,
43 // but may not modify the contents. It is like the difference between
44 // (MyClass * const) and (const MyClass *).
45 //
46 // In order to use PointerTo, it is necessary that the thing pointed
47 // to--MyClass in the above example--either inherits from
48 // ReferenceCount, or is a proxy built with RefCountProxy or
49 // RefCountObj (see referenceCount.h). However, also see
50 // PointerToArray, which does not have this restriction.
51 //
52 // It is crucial that the PointerTo object is only used to refer to
53 // objects allocated from the free store, for which delete is a
54 // sensible thing to do. If you assign a PointerTo to an automatic
55 // variable (allocated from the stack, for instance), bad things will
56 // certainly happen when the reference count reaches zero and it tries
57 // to delete it.
58 //
59 // It's also important to remember that, as always, a virtual
60 // destructor is required if you plan to support polymorphism. That
61 // is, if you define a PointerTo to some base type, and assign to it
62 // instances of a class derived from that base class, the base class
63 // must have a virtual destructor in order to properly destruct the
64 // derived object when it is deleted.
65 //
66 ////////////////////////////////////////////////////////////////////
67 
68 #include "pandabase.h"
69 #include "pointerToBase.h"
70 #include "register_type.h"
71 
72 ////////////////////////////////////////////////////////////////////
73 // Class : PointerTo
74 // Description : PointerTo is a template class which implements a
75 // smart pointer to an object derived from
76 // ReferenceCount.
77 ////////////////////////////////////////////////////////////////////
78 template <class T>
79 class PointerTo : public PointerToBase<T> {
80 public:
81  typedef TYPENAME PointerToBase<T>::To To;
82 PUBLISHED:
83  INLINE PointerTo(To *ptr = (To *)NULL);
84  INLINE PointerTo(const PointerTo<T> &copy);
85  INLINE ~PointerTo();
86 
87 public:
88 #ifdef USE_MOVE_SEMANTICS
89  INLINE PointerTo(PointerTo<T> &&from) NOEXCEPT;
90  INLINE PointerTo<T> &operator = (PointerTo<T> &&from) NOEXCEPT;
91 #endif
92 
93  INLINE To &operator *() const;
94  INLINE To *operator -> () const;
95  // MSVC.NET 2005 insists that we use T *, and not To *, here.
96  INLINE operator T *() const;
97 
98  INLINE T *&cheat();
99 
100 PUBLISHED:
101  // When downcasting to a derived class from a PointerTo<BaseClass>,
102  // C++ would normally require you to cast twice: once to an actual
103  // BaseClass pointer, and then again to your desired pointer. You
104  // can use the handy function p() to avoid this first cast and make
105  // your code look a bit cleaner.
106 
107  // e.g. instead of (MyType *)(BaseClass *)ptr, use (MyType *)ptr.p()
108 
109  // If your base class is a derivative of TypedObject, you might want
110  // to use the DCAST macro defined in typedObject.h instead,
111  // e.g. DCAST(MyType, ptr). This provides a clean downcast that
112  // doesn't require .p() or any double-casting, and it can be
113  // run-time checked for correctness.
114  INLINE To *p() const;
115 
116  INLINE PointerTo<T> &operator = (To *ptr);
117  INLINE PointerTo<T> &operator = (const PointerTo<T> &copy);
118 
119  // These functions normally wouldn't need to be redefined here, but
120  // we do so anyway just to help out interrogate (which doesn't seem
121  // to want to automatically export the PointerToBase class). When
122  // this works again in interrogate, we can remove these.
123  INLINE bool is_null() const { return PointerToBase<T>::is_null(); }
124  INLINE void clear() { PointerToBase<T>::clear(); }
125 };
126 
127 
128 ////////////////////////////////////////////////////////////////////
129 // Class : ConstPointerTo
130 // Description : A ConstPointerTo is similar to a PointerTo, except it
131 // keeps a const pointer to the thing.
132 //
133 // (Actually, it keeps a non-const pointer, because it
134 // must be allowed to adjust the reference counts, and
135 // it must be able to delete it when the reference count
136 // goes to zero. But it presents only a const pointer
137 // to the outside world.)
138 //
139 // Notice that a PointerTo may be assigned to a
140 // ConstPointerTo, but a ConstPointerTo may not be
141 // assigned to a PointerTo.
142 ////////////////////////////////////////////////////////////////////
143 template <class T>
144 class ConstPointerTo : public PointerToBase<T> {
145 public:
146  typedef TYPENAME PointerToBase<T>::To To;
147 PUBLISHED:
148  INLINE ConstPointerTo(const To *ptr = (const To *)NULL);
149  INLINE ConstPointerTo(const PointerTo<T> &copy);
150  INLINE ConstPointerTo(const ConstPointerTo<T> &copy);
151  INLINE ~ConstPointerTo();
152 
153 public:
154 #ifdef USE_MOVE_SEMANTICS
155  INLINE ConstPointerTo(PointerTo<T> &&from) NOEXCEPT;
156  INLINE ConstPointerTo(ConstPointerTo<T> &&from) NOEXCEPT;
157  INLINE ConstPointerTo<T> &operator = (PointerTo<T> &&from) NOEXCEPT;
158  INLINE ConstPointerTo<T> &operator = (ConstPointerTo<T> &&from) NOEXCEPT;
159 #endif
160 
161  INLINE const To &operator *() const;
162  INLINE const To *operator -> () const;
163  INLINE operator const T *() const;
164 
165  INLINE const T *&cheat();
166 
167 PUBLISHED:
168  INLINE const To *p() const;
169 
170  INLINE ConstPointerTo<T> &operator = (const To *ptr);
171  INLINE ConstPointerTo<T> &operator = (const PointerTo<T> &copy);
172  INLINE ConstPointerTo<T> &operator = (const ConstPointerTo<T> &copy);
173 
174  // This functions normally wouldn't need to be redefined here, but
175  // we do so anyway just to help out interrogate (which doesn't seem
176  // to want to automatically export the PointerToBase class). When
177  // this works again in interrogate, we can remove this.
178  INLINE void clear() { PointerToBase<T>::clear(); }
179 };
180 
181 
182 // The existence of these functions makes it possible to sort vectors
183 // of PointerTo objects without incurring the cost of unnecessary
184 // reference count changes. The performance difference is dramatic!
185 template <class T>
186 void swap(PointerTo<T> &one, PointerTo<T> &two) NOEXCEPT {
187  one.swap(two);
188 }
189 
190 template <class T>
191 void swap(ConstPointerTo<T> &one, ConstPointerTo<T> &two) NOEXCEPT {
192  one.swap(two);
193 }
194 
195 
196 // Finally, we'll define a couple of handy abbreviations to save on
197 // all that wasted typing time.
198 
199 #define PT(type) PointerTo< type >
200 #define CPT(type) ConstPointerTo< type >
201 
202 // Now that we have defined PointerTo, we can define what it means to
203 // take the TypeHandle of a PointerTo object.
204 
205 template<class T>
206 INLINE TypeHandle _get_type_handle(const PointerTo<T> *) {
207  return T::get_class_type();
208 }
209 
210 template<class T>
211 INLINE TypeHandle _get_type_handle(const ConstPointerTo<T> *) {
212  return T::get_class_type();
213 }
214 
215 
216 #include "pointerTo.I"
217 
218 #endif
void clear()
A convenient way to set the PointerTo object to NULL.
const T *& cheat()
Returns a reference to the underlying pointer.
Definition: pointerTo.I:311
const To * p() const
Returns an ordinary pointer instead of a ConstPointerTo.
Definition: pointerTo.I:324
This is the base class for PointerTo and ConstPointerTo.
Definition: pointerToBase.h:32
To * p() const
Returns an ordinary pointer instead of a PointerTo.
Definition: pointerTo.I:137
bool is_null() const
Returns true if the PointerTo is a NULL pointer, false otherwise.
Definition: pointerToVoid.I:54
A ConstPointerTo is similar to a PointerTo, except it keeps a const pointer to the thing...
Definition: pointerTo.h:144
PointerTo is a template class which implements a smart pointer to an object derived from ReferenceCou...
Definition: pointerTo.h:79
T *& cheat()
Returns a reference to the underlying pointer.
Definition: pointerTo.I:124
TypeHandle is the identifier used to differentiate C++ class types.
Definition: typeHandle.h:85