ACE智能指针

Bound_Ptr.h

  1 // -*- C++ -*-
  2 
  3 //=============================================================================
  4 /**
  5  *  @file    Bound_Ptr.h
  6  *
  7  *  $Id: Bound_Ptr.h 82723 2008-09-16 09:35:44Z johnnyw $
  8  *
  9  *  @author Christopher Kohlhoff <chris@kohlhoff.com>
 10  *  @author Boris Kolpackov <boris@codesynthesis.com>
 11  */
 12 //=============================================================================
 13 
 14 #ifndef ACE_BOUND_PTR_H
 15 #define ACE_BOUND_PTR_H
 16 
 17 #include /**/ "ace/pre.h"
 18 
 19 #include /**/ "ace/config-all.h"
 20 
 21 #if !defined (ACE_LACKS_PRAGMA_ONCE)
 22 # pragma once
 23 #endif /* ACE_LACKS_PRAGMA_ONCE */
 24 
 25 #include "ace/Auto_Ptr.h"
 26 
 27 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
 28 
 29 /**
 30  * @class ACE_Bound_Ptr_Counter
 31  *
 32  * @brief An ACE_Bound_Ptr_Counter<ACE_LOCK> object encapsulates an
 33  *        object reference count.
 34  *
 35  * Do not use this class directly, use ACE_Strong_Bound_Ptr or
 36  * ACE_Weak_Bound_Ptr instead.
 37  */
 38 template <class ACE_LOCK>
 39 class ACE_Bound_Ptr_Counter
 40 {
 41 public:
 42   /// Declare the dynamic allocation hooks.
 43   ACE_ALLOC_HOOK_DECLARE;
 44 
 45   ACE_Bound_Ptr_Counter (long init_obj_ref_count = 0);
 46   ~ACE_Bound_Ptr_Counter (void);
 47 
 48   /// Create a ACE_Bound_Ptr_Counter<ACE_LOCK> and initialize the
 49   /// reference count to indicate ownership by a strong pointer.
 50   static ACE_Bound_Ptr_Counter<ACE_LOCK> *create_strong (void);
 51 
 52   /// Increase both the object and counter reference counts and return
 53   /// the new object reference count. A return value of -1 indicates
 54   /// that the object has already been destroyed.
 55   static long attach_strong (ACE_Bound_Ptr_Counter<ACE_LOCK> *counter);
 56 
 57   /// Decreases both the object and counter reference counts and
 58   /// deletes whichever has no more references. Returns the new object
 59   /// reference count.
 60   static long detach_strong (ACE_Bound_Ptr_Counter<ACE_LOCK> *counter);
 61 
 62   /// Create a ACE_Bound_Ptr_Counter<ACE_LOCK> and initialize the
 63   /// reference count to indicate no ownership.
 64   static ACE_Bound_Ptr_Counter<ACE_LOCK> *create_weak (void);
 65 
 66   /// Increase the counter reference count and return argument.
 67   static void attach_weak (ACE_Bound_Ptr_Counter<ACE_LOCK> *counter);
 68 
 69   /// Decreases the counter reference count and deletes the counter if
 70   /// it has no more references.
 71   static void detach_weak (ACE_Bound_Ptr_Counter<ACE_LOCK> *counter);
 72 
 73   /// Determine whether the object has been deleted.
 74   static bool object_was_deleted (ACE_Bound_Ptr_Counter<ACE_LOCK> *counter);
 75 
 76 private:
 77 
 78   /// Allocate a new ACE_Bound_Ptr_Counter<ACE_LOCK> instance,
 79   /// returning NULL if it cannot be created.
 80   static ACE_Bound_Ptr_Counter<ACE_LOCK> *internal_create (long init_obj_ref_count);
 81 
 82 private:
 83 
 84   /// Reference count of underlying object. Is set to -1 once the
 85   /// object has been destroyed to indicate to all weak pointers that
 86   /// it is no longer valid.
 87   long obj_ref_count_;
 88 
 89   /// Reference count of this counter.
 90   long self_ref_count_;
 91 
 92   /// Mutex variable to synchronize access to the reference counts.
 93   ACE_LOCK lock_;
 94 };
 95 
 96 // Forward decl.
 97 template <class X, class ACE_LOCK> class ACE_Weak_Bound_Ptr;
 98 
 99 /**
100  * @class ACE_Strong_Bound_Ptr
101  *
102  * @brief This class implements support for a reference counted
103  *        pointer.
104  *
105  * Assigning or copying instances of an ACE_Strong_Bound_Ptr will
106  * automatically increment the reference count of the underlying object.
107  * When the last instance of an ACE_Strong_Bound_Ptr that references a
108  * particular object is destroyed or overwritten, it will invoke delete
109  * on its underlying pointer.
110  */
111 template <class X, class ACE_LOCK>
112 class ACE_Strong_Bound_Ptr
113 {
114 public:
115   /// Constructor that initializes an ACE_Strong_Bound_Ptr to point to the
116   /// object \<p\> immediately.
117   explicit ACE_Strong_Bound_Ptr (X *p = 0);
118 
119   /// Constructor that initializes an ACE_Strong_Bound_Ptr by stealing
120   /// ownership of an object from an auto_ptr.
121   explicit ACE_Strong_Bound_Ptr (auto_ptr<X> p);
122 
123   /// Copy constructor binds @c this and @a r to the same object.
124   ACE_Strong_Bound_Ptr (const ACE_Strong_Bound_Ptr<X, ACE_LOCK> &r);
125 
126   /// Constructor binds @c this and @a r to the same object.
127   ACE_Strong_Bound_Ptr (const ACE_Weak_Bound_Ptr<X, ACE_LOCK> &r);
128 
129   /// Copy constructor binds @c this and @a r to the same object if
130   /// Y* can be implicitly converted to X*.
131   template <class Y>
132   ACE_Strong_Bound_Ptr (const ACE_Strong_Bound_Ptr<Y, ACE_LOCK> &r)
133       : counter_ (r.counter_),
134         ptr_ (dynamic_cast<X_t*>(r.ptr_))
135   {
136     // This ctor is temporarily defined here to increase our chances
137     // of being accepted by broken compilers.
138     //
139     COUNTER::attach_strong (this->counter_);
140   }
141 
142   /// Destructor.
143   ~ACE_Strong_Bound_Ptr (void);
144 
145   /// Assignment operator that binds @c this and @a r to the same object.
146   void operator = (const ACE_Strong_Bound_Ptr<X, ACE_LOCK> &r);
147 
148   /// Assignment operator that binds @c this and @a r to the same object.
149   void operator = (const ACE_Weak_Bound_Ptr<X, ACE_LOCK> &r);
150 
151   /// Assignment operator that binds @c this and @a r to the same object
152   /// if Y* can be implicitly converted to X*.
153   template <class Y>
154   ACE_Weak_Bound_Ptr<X, ACE_LOCK>&
155   operator= (const ACE_Strong_Bound_Ptr<Y, ACE_LOCK> &r)
156   {
157     // This operator is temporarily defined here to increase our chances
158     // of being accepted by broken compilers.
159     //
160 
161     // This will work if &r == this, by first increasing the ref count
162 
163     COUNTER *new_counter = r.counter_;
164     X* new_ptr = dynamic_cast<X_t*> (r.ptr_);
165     COUNTER::attach_strong (new_counter);
166     if (COUNTER::detach_strong (this->counter_) == 0)
167       delete this->ptr_;
168     this->counter_ = new_counter;
169     this->ptr_ = new_ptr;
170 
171     return *this;
172   }
173 
174   /// Equality operator that returns @c true if both
175   /// ACE_Strong_Bound_Ptr instances point to the same underlying
176   /// object.
177   /**
178    * @note It also returns @c true if both objects have just been
179    *       instantiated and not used yet.
180    */
181   bool operator == (const ACE_Strong_Bound_Ptr<X, ACE_LOCK> &r) const;
182 
183   /// Equality operator that returns true if the ACE_Strong_Bound_Ptr
184   /// and ACE_Weak_Bound_Ptr objects point to the same underlying
185   /// object.
186   /**
187    * @note It also returns @c true if both objects have just been
188    *       instantiated and not used yet.
189    */
190   bool operator == (const ACE_Weak_Bound_Ptr<X, ACE_LOCK> &r) const;
191 
192   /// Equality operator that returns @c true if the
193   /// ACE_Strong_Bound_Ptr and the raw pointer point to the same
194   /// underlying object.
195   bool operator == (X *p) const;
196 
197   /// Inequality operator, which is the opposite of equality.
198   bool operator != (const ACE_Strong_Bound_Ptr<X, ACE_LOCK> &r) const;
199 
200   /// Inequality operator, which is the opposite of equality.
201   bool operator != (const ACE_Weak_Bound_Ptr<X, ACE_LOCK> &r) const;
202 
203   /// Inequality operator, which is the opposite of equality.
204   bool operator != (X *p) const;
205 
206   /// Redirection operator
207   X *operator-> (void) const;
208 
209   /// Dereference operator
210   X &operator * (void) const;
211 
212   /// Get the pointer value.
213   X *get (void) const;
214 
215   /// Resets the ACE_Strong_Bound_Ptr to refer to a different
216   /// underlying object.
217   void reset (X *p = 0);
218 
219   /// Resets the ACE_Strong_Bound_Ptr to refer to a different
220   /// underlying object, ownership of which is stolen from the
221   /// auto_ptr.
222   void reset (auto_ptr<X> p);
223 
224   /// Allows us to check for NULL on all ACE_Strong_Bound_Ptr
225   /// objects.
226   bool null (void) const;
227 
228   /// Declare the dynamic allocation hooks.
229   ACE_ALLOC_HOOK_DECLARE;
230 
231 private:
232   typedef X X_t; // This indirection is for Borland C++.
233 
234   friend class ACE_Weak_Bound_Ptr<X, ACE_LOCK>;
235 
236   template <class Y, class L>
237   friend class ACE_Strong_Bound_Ptr;
238 
239   /// The ACE_Bound_Ptr_Counter type.
240   typedef ACE_Bound_Ptr_Counter<ACE_LOCK> COUNTER;
241 
242   /// The reference counter.
243   COUNTER *counter_;
244 
245   /// The underlying object.
246   X *ptr_;
247 };
248 
249 /**
250  * @class ACE_Weak_Bound_Ptr
251  *
252  * @brief This class implements support for a weak pointer that complements
253  * ACE_Strong_Bound_Ptr.
254  *
255  * Unlike ACE_Strong_Bound_Ptr, assigning or copying instances of an
256  * ACE_Weak_Bound_Ptr will not automatically increment the reference
257  * count of the underlying object. What ACE_Weak_Bound_Ptr does is
258  * preserve the knowledge that the object is in fact reference
259  * counted, and thus provides an alternative to raw pointers where
260  * non-ownership associations must be maintained. When the last
261  * instance of an ACE_Strong_Bound_Ptr that references a particular
262  * object is destroyed or overwritten, the corresponding
263  * ACE_Weak_Bound_Ptr instances are set to NULL.
264  */
265 template <class X, class ACE_LOCK>
266 class ACE_Weak_Bound_Ptr
267 {
268 public:
269   /// Constructor that initializes an ACE_Weak_Bound_Ptr to point to
270   /// the object \<p\> immediately.
271   explicit ACE_Weak_Bound_Ptr (X *p = 0);
272 
273   /// Copy constructor binds @c this and @a r to the same object.
274   ACE_Weak_Bound_Ptr (const ACE_Weak_Bound_Ptr<X, ACE_LOCK> &r);
275 
276   /// Constructor binds @c this and @a r to the same object.
277   ACE_Weak_Bound_Ptr (const ACE_Strong_Bound_Ptr<X, ACE_LOCK> &r);
278 
279   /// Destructor.
280   ~ACE_Weak_Bound_Ptr (void);
281 
282   /// Assignment operator that binds @c this and @a r to the same object.
283   void operator = (const ACE_Weak_Bound_Ptr<X, ACE_LOCK> &r);
284 
285   /// Assignment operator that binds @c this and @a r to the same object.
286   void operator = (const ACE_Strong_Bound_Ptr<X, ACE_LOCK> &r);
287 
288   /// Equality operator that returns @c true if both
289   /// ACE_Weak_Bound_Ptr objects point to the same underlying object.
290   /**
291    * @note It also returns @c true if both objects have just been
292    *       instantiated and not used yet.
293    */
294   bool operator == (const ACE_Weak_Bound_Ptr<X, ACE_LOCK> &r) const;
295 
296   /// Equality operator that returns @c true if the ACE_Weak_Bound_Ptr
297   /// and ACE_Strong_Bound_Ptr objects point to the same underlying
298   /// object.
299   /**
300    * @note It also returns @c true if both objects have just been
301    *       instantiated and not used yet.
302    */
303   bool operator == (const ACE_Strong_Bound_Ptr<X, ACE_LOCK> &r) const;
304 
305   /// Equality operator that returns @c true if the ACE_Weak_Bound_Ptr
306   /// and the raw pointer point to the same underlying object.
307   bool operator == (X *p) const;
308 
309   /// Inequality operator, which is the opposite of equality.
310   bool operator != (const ACE_Weak_Bound_Ptr<X, ACE_LOCK> &r) const;
311 
312   /// Inequality operator, which is the opposite of equality.
313   bool operator != (const ACE_Strong_Bound_Ptr<X, ACE_LOCK> &r) const;
314 
315   /// Inequality operator, which is the opposite of equality.
316   bool operator != (X *p) const;
317 
318   /// Redirection operator.
319   /**
320    * It returns a temporary strong pointer and makes use of the
321    * chaining properties of operator-> to ensure that the underlying
322    * object does not disappear while you are using it.  If you are
323    * certain of the lifetimes of the object, and do not want to incur
324    * the locking overhead, then use the unsafe_get method instead.
325    */
326   ACE_Strong_Bound_Ptr<X, ACE_LOCK> operator-> (void) const;
327 
328   /// Obtain a strong pointer corresponding to this weak pointer. This
329   /// function is useful to create a temporary strong pointer for
330   /// conversion to a reference.
331   ACE_Strong_Bound_Ptr<X, ACE_LOCK> strong (void) const;
332 
333   /// Get the pointer value. Warning: this does not affect the
334   /// reference count of the underlying object, so it may disappear on
335   /// you while you are using it if you are not careful.
336   X *unsafe_get (void) const;
337 
338   /// Resets the ACE_Weak_Bound_Ptr to refer to a different underlying
339   /// object.
340   void reset (X *p = 0);
341 
342   /// Increment the reference count on the underlying object.
343   /**
344    * Returns the new reference count on the object. This function may
345    * be used to integrate the bound pointers into an external
346    * reference counting mechanism such as those used by COM or CORBA
347    * servants.
348    */
349   long add_ref (void);
350 
351   /// Decrement the reference count on the underlying object, which is deleted
352   /// if the count has reached zero.
353   /**
354    * Returns the new reference count on the object.  This function may
355    * be used to integrate the bound pointers into an external
356    * reference counting mechanism such as those used by COM or CORBA
357    * servants.
358    */
359   long remove_ref (void);
360 
361   /// Allows us to check for NULL on all ACE_Weak_Bound_Ptr objects.
362   bool null (void) const;
363 
364   /// Declare the dynamic allocation hooks.
365   ACE_ALLOC_HOOK_DECLARE;
366 
367 private:
368   typedef X X_t; // This indirection is for Borland C++.
369 
370   friend class ACE_Strong_Bound_Ptr<X, ACE_LOCK>;
371 
372   /// The ACE_Bound_Ptr_Counter type.
373   typedef ACE_Bound_Ptr_Counter<ACE_LOCK> COUNTER;
374 
375   /// The reference counter.
376   COUNTER *counter_;
377 
378   /// The underlying object.
379   X *ptr_;
380 };
381 
382 ACE_END_VERSIONED_NAMESPACE_DECL
383 
384 #include "ace/Bound_Ptr.inl"
385 
386 #include /**/ "ace/post.h"
387 
388 #endif /* ACE_BOUND_PTR_H */

Bound_Ptr.inl

  1 /* -*- C++ -*- */
  2 // $Id: Bound_Ptr.inl 82723 2008-09-16 09:35:44Z johnnyw $
  3 
  4 // Bound_Ptr.i
  5 
  6 #include "ace/Guard_T.h"
  7 #if !defined (ACE_NEW_THROWS_EXCEPTIONS)
  8 #  include "ace/Log_Msg.h"
  9 #endif /* ACE_NEW_THROWS_EXCEPTIONS */
 10 
 11 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
 12 
 13 template <class ACE_LOCK> inline ACE_Bound_Ptr_Counter<ACE_LOCK> *
 14 ACE_Bound_Ptr_Counter<ACE_LOCK>::internal_create (long init_obj_ref_count)
 15 {
 16   ACE_Bound_Ptr_Counter<ACE_LOCK> *temp = 0;
 17   ACE_NEW_RETURN (temp,
 18                   ACE_Bound_Ptr_Counter<ACE_LOCK> (init_obj_ref_count),
 19                   0);
 20   return temp;
 21 }
 22 
 23 template <class ACE_LOCK> inline ACE_Bound_Ptr_Counter<ACE_LOCK> *
 24 ACE_Bound_Ptr_Counter<ACE_LOCK>::create_strong (void)
 25 {
 26   // Set initial object reference count to 1.
 27   ACE_Bound_Ptr_Counter<ACE_LOCK> *temp = internal_create (1);
 28 #if defined (ACE_NEW_THROWS_EXCEPTIONS)
 29   if (temp == 0)
 30     ACE_throw_bad_alloc;
 31 #else
 32   ACE_ASSERT (temp != 0);
 33 #endif /* ACE_NEW_THROWS_EXCEPTIONS */
 34   return temp;
 35 }
 36 
 37 
 38 
 39 template <class ACE_LOCK> inline long
 40 ACE_Bound_Ptr_Counter<ACE_LOCK>::attach_strong (ACE_Bound_Ptr_Counter<ACE_LOCK>* counter)
 41 {
 42   ACE_GUARD_RETURN (ACE_LOCK, guard, counter->lock_, -1);
 43 
 44   // Can't attach a strong pointer to an object that has already been deleted.
 45   if (counter->obj_ref_count_ == -1)
 46     return -1;
 47 
 48   long new_obj_ref_count = ++counter->obj_ref_count_;
 49   ++counter->self_ref_count_;
 50 
 51   return new_obj_ref_count;
 52 }
 53 
 54 template <class ACE_LOCK> inline long
 55 ACE_Bound_Ptr_Counter<ACE_LOCK>::detach_strong (ACE_Bound_Ptr_Counter<ACE_LOCK>* counter)
 56 {
 57   ACE_Bound_Ptr_Counter<ACE_LOCK> *counter_del = 0;
 58   long new_obj_ref_count;
 59 
 60   {
 61     ACE_GUARD_RETURN (ACE_LOCK, guard, counter->lock_, -1);
 62 
 63     if ((new_obj_ref_count = --counter->obj_ref_count_) == 0)
 64       // Change the object reference count to -1 to indicate that the
 65       // object has been deleted, as opposed to a weak pointer that
 66       // simply hasn't had any strong pointers created from it yet.
 67       counter->obj_ref_count_ = -1;
 68 
 69     if (--counter->self_ref_count_ == 0)
 70       // Since counter contains the lock held by the ACE_Guard, the
 71       // guard needs to be released before freeing the memory holding
 72       // the lock. So save the pointer to free, then release, then
 73       // free.
 74       counter_del = counter;
 75 
 76   }  // Release the lock
 77 
 78   delete counter_del;
 79 
 80   return new_obj_ref_count;
 81 }
 82 
 83 template <class ACE_LOCK> inline ACE_Bound_Ptr_Counter<ACE_LOCK> *
 84 ACE_Bound_Ptr_Counter<ACE_LOCK>::create_weak (void)
 85 {
 86   // Set initial object reference count to 0.
 87 
 88   ACE_Bound_Ptr_Counter<ACE_LOCK> *temp = internal_create (0);
 89 #if defined (ACE_NEW_THROWS_EXCEPTIONS)
 90   if (temp == 0)
 91     ACE_throw_bad_alloc;
 92 #else
 93   ACE_ASSERT (temp != 0);
 94 #endif /* ACE_NEW_THROWS_EXCEPTIONS */
 95   return temp;
 96 }
 97 
 98 template <class ACE_LOCK> inline void
 99 ACE_Bound_Ptr_Counter<ACE_LOCK>::attach_weak (ACE_Bound_Ptr_Counter<ACE_LOCK>* counter)
100 {
101   ACE_GUARD (ACE_LOCK, guard, counter->lock_);
102 
103   ++counter->self_ref_count_;
104 }
105 
106 template <class ACE_LOCK> inline void
107 ACE_Bound_Ptr_Counter<ACE_LOCK>::detach_weak (ACE_Bound_Ptr_Counter<ACE_LOCK>* counter)
108 {
109   ACE_Bound_Ptr_Counter<ACE_LOCK> *counter_del = 0;
110 
111   {
112     ACE_GUARD (ACE_LOCK, guard, counter->lock_);
113 
114     if (--counter->self_ref_count_ == 0)
115       // Since counter contains the lock held by the ACE_Guard, the
116       // guard needs to be released before freeing the memory holding
117       // the lock. So save the pointer to free, then release, then
118       // free.
119       counter_del = counter;
120 
121   }  // Release the lock
122 
123   delete counter_del;
124 }
125 
126 template <class ACE_LOCK> inline bool
127 ACE_Bound_Ptr_Counter<ACE_LOCK>::object_was_deleted (ACE_Bound_Ptr_Counter<ACE_LOCK> *counter)
128 {
129   ACE_GUARD_RETURN (ACE_LOCK, guard, counter->lock_, 0);
130 
131   return counter->obj_ref_count_ == -1;
132 }
133 
134 template <class ACE_LOCK> inline
135 ACE_Bound_Ptr_Counter<ACE_LOCK>::ACE_Bound_Ptr_Counter (long init_obj_ref_count)
136   : obj_ref_count_ (init_obj_ref_count),
137     self_ref_count_ (1)
138 {
139 }
140 
141 template <class ACE_LOCK> inline
142 ACE_Bound_Ptr_Counter<ACE_LOCK>::~ACE_Bound_Ptr_Counter (void)
143 {
144 }
145 
146 template <class X, class ACE_LOCK> inline
147 ACE_Strong_Bound_Ptr<X, ACE_LOCK>::ACE_Strong_Bound_Ptr (X *p)
148   : counter_ (COUNTER::create_strong ()),
149     ptr_ (p)
150 {
151 }
152 
153 template <class X, class ACE_LOCK> inline
154 ACE_Strong_Bound_Ptr<X, ACE_LOCK>::ACE_Strong_Bound_Ptr (auto_ptr<X> p)
155   : counter_ (COUNTER::create_strong ()),
156     ptr_ (p.release())
157 {
158 }
159 
160 template <class X, class ACE_LOCK> inline
161 ACE_Strong_Bound_Ptr<X, ACE_LOCK>::ACE_Strong_Bound_Ptr (const ACE_Strong_Bound_Ptr<X, ACE_LOCK> &r)
162   : counter_ (r.counter_),
163     ptr_ (r.ptr_)
164 {
165   COUNTER::attach_strong (this->counter_);
166 }
167 
168 template <class X, class ACE_LOCK> inline
169 ACE_Strong_Bound_Ptr<X, ACE_LOCK>::ACE_Strong_Bound_Ptr (const ACE_Weak_Bound_Ptr<X, ACE_LOCK> &r)
170   : counter_ (r.counter_),
171     ptr_ (r.ptr_)
172 {
173   // When creating a strong pointer from a weak one we can't assume that the
174   // underlying object still exists. Therefore we must check for a return value
175   // of -1, which indicates that the object has been destroyed.
176   if (COUNTER::attach_strong (this->counter_) == -1)
177     {
178       // Underlying object has already been deleted, so set this pointer to null.
179       this->counter_ = COUNTER::create_strong ();
180       this->ptr_ = 0;
181     }
182 }
183 
184 template <class X, class ACE_LOCK> inline
185 ACE_Strong_Bound_Ptr<X, ACE_LOCK>::~ACE_Strong_Bound_Ptr (void)
186 {
187   if (COUNTER::detach_strong (this->counter_) == 0)
188     delete this->ptr_;
189 }
190 
191 template <class X, class ACE_LOCK> inline void
192 ACE_Strong_Bound_Ptr<X, ACE_LOCK>::operator = (const ACE_Strong_Bound_Ptr<X, ACE_LOCK> &rhs)
193 {
194   // This will work if &r == this, by first increasing the ref count, but
195   // why go through all that?
196   if (&rhs == this)
197     return;
198 
199   COUNTER *new_counter = rhs.counter_;
200   X_t *new_ptr = rhs.ptr_;
201   COUNTER::attach_strong (new_counter);
202   if (COUNTER::detach_strong (this->counter_) == 0)
203     delete this->ptr_;
204   this->counter_ = new_counter;
205   this->ptr_ = new_ptr;
206 }
207 
208 template <class X, class ACE_LOCK> inline void
209 ACE_Strong_Bound_Ptr<X, ACE_LOCK>::operator = (const ACE_Weak_Bound_Ptr<X, ACE_LOCK> &rhs)
210 {
211   // This will work if &r == this, by first increasing the ref count, but
212   // why go through all that?
213   if (&rhs == this)
214     return;
215 
216   COUNTER *new_counter = rhs.counter_;
217   X_t *new_ptr = rhs.ptr_;
218 
219   // When creating a strong pointer from a weak one we can't assume that the
220   // underlying object still exists. Therefore we must check for a return value
221   // of -1, which indicates that the object has been destroyed.
222   if (COUNTER::attach_strong (new_counter) == -1)
223     {
224       // Underlying object has already been deleted, so set this pointer to null.
225       new_counter = COUNTER::create_strong ();
226       new_ptr = 0;
227     }
228 
229   if (COUNTER::detach_strong (this->counter_) == 0)
230     delete this->ptr_;
231   this->counter_ = new_counter;
232   this->ptr_ = new_ptr;
233 }
234 
235 template <class X, class ACE_LOCK> inline bool
236 ACE_Strong_Bound_Ptr<X, ACE_LOCK>::operator== (const ACE_Strong_Bound_Ptr<X, ACE_LOCK> &r) const
237 {
238   return this->ptr_ == r.ptr_;
239 }
240 
241 template <class X, class ACE_LOCK> inline bool
242 ACE_Strong_Bound_Ptr<X, ACE_LOCK>::operator== (const ACE_Weak_Bound_Ptr<X, ACE_LOCK> &r) const
243 {
244   // Use the weak pointer's operator== since it will check for null.
245   return r == *this;
246 }
247 
248 template <class X, class ACE_LOCK> inline bool
249 ACE_Strong_Bound_Ptr<X, ACE_LOCK>::operator== (X *p) const
250 {
251   return this->ptr_ == p;
252 }
253 
254 template <class X, class ACE_LOCK> inline bool
255 ACE_Strong_Bound_Ptr<X, ACE_LOCK>::operator!= (const ACE_Strong_Bound_Ptr<X, ACE_LOCK> &r) const
256 {
257   return this->ptr_ != r.ptr_;
258 }
259 
260 template <class X, class ACE_LOCK> inline bool
261 ACE_Strong_Bound_Ptr<X, ACE_LOCK>::operator!= (const ACE_Weak_Bound_Ptr<X, ACE_LOCK> &r) const
262 {
263   // Use the weak pointer's operator!= since it will check for null.
264   return r != *this;
265 }
266 
267 template <class X, class ACE_LOCK> inline bool
268 ACE_Strong_Bound_Ptr<X, ACE_LOCK>::operator!= (X *p) const
269 {
270   return this->ptr_ != p;
271 }
272 
273 template <class X, class ACE_LOCK> inline X *
274 ACE_Strong_Bound_Ptr<X, ACE_LOCK>::operator-> (void) const
275 {
276   return this->ptr_;
277 }
278 
279 template<class X, class ACE_LOCK> inline X &
280 ACE_Strong_Bound_Ptr<X, ACE_LOCK>::operator *() const
281 {
282   return *this->ptr_;
283 }
284 
285 template <class X, class ACE_LOCK> inline X*
286 ACE_Strong_Bound_Ptr<X, ACE_LOCK>::get (void) const
287 {
288   return this->ptr_;
289 }
290 
291 template <class X, class ACE_LOCK> inline bool
292 ACE_Strong_Bound_Ptr<X, ACE_LOCK>::null (void) const
293 {
294   return this->ptr_ == 0;
295 }
296 
297 template<class X, class ACE_LOCK> inline void
298 ACE_Strong_Bound_Ptr<X, ACE_LOCK>::reset (X *p)
299 {
300   COUNTER *old_counter = this->counter_;
301   X_t *old_ptr = this->ptr_;
302   this->counter_ = COUNTER::create_strong ();
303   this->ptr_ = p;
304   if (COUNTER::detach_strong (old_counter) == 0)
305     delete old_ptr;
306 }
307 
308 template<class X, class ACE_LOCK> inline void
309 ACE_Strong_Bound_Ptr<X, ACE_LOCK>::reset (auto_ptr<X> p)
310 {
311   COUNTER *old_counter = this->counter_;
312   X_t *old_ptr = this->ptr_;
313   this->counter_ = COUNTER::create_strong ();
314   this->ptr_ = p.release ();
315   if (COUNTER::detach_strong (old_counter) == 0)
316     delete old_ptr;
317 }
318 
319 template <class X, class ACE_LOCK> inline
320 ACE_Weak_Bound_Ptr<X, ACE_LOCK>::ACE_Weak_Bound_Ptr (X *p)
321   : counter_ (COUNTER::create_weak ()),
322     ptr_ (p)
323 {
324 }
325 
326 template <class X, class ACE_LOCK> inline
327 ACE_Weak_Bound_Ptr<X, ACE_LOCK>::ACE_Weak_Bound_Ptr (const ACE_Weak_Bound_Ptr<X, ACE_LOCK> &r)
328   : counter_ (r.counter_),
329     ptr_ (r.ptr_)
330 {
331   COUNTER::attach_weak (this->counter_);
332 }
333 
334 template <class X, class ACE_LOCK> inline
335 ACE_Weak_Bound_Ptr<X, ACE_LOCK>::ACE_Weak_Bound_Ptr (const ACE_Strong_Bound_Ptr<X, ACE_LOCK> &r)
336   : counter_ (r.counter_),
337     ptr_ (r.ptr_)
338 {
339   COUNTER::attach_weak (this->counter_);
340 }
341 
342 template <class X, class ACE_LOCK> inline
343 ACE_Weak_Bound_Ptr<X, ACE_LOCK>::~ACE_Weak_Bound_Ptr (void)
344 {
345   COUNTER::detach_weak (this->counter_);
346 }
347 
348 template <class X, class ACE_LOCK> inline void
349 ACE_Weak_Bound_Ptr<X, ACE_LOCK>::operator = (const ACE_Weak_Bound_Ptr<X, ACE_LOCK> &rhs)
350 {
351   // This will work if &rhs == this, by first increasing the ref count
352   COUNTER *new_counter = rhs.counter_;
353   COUNTER::attach_weak (new_counter);
354   COUNTER::detach_weak (this->counter_);
355   this->counter_ = new_counter;
356   this->ptr_ = rhs.ptr_;
357 }
358 
359 template <class X, class ACE_LOCK> inline void
360 ACE_Weak_Bound_Ptr<X, ACE_LOCK>::operator = (const ACE_Strong_Bound_Ptr<X, ACE_LOCK> &rhs)
361 {
362   // This will work if &rhs == this, by first increasing the ref count
363   COUNTER *new_counter = rhs.counter_;
364   COUNTER::attach_weak (new_counter);
365   COUNTER::detach_weak (this->counter_);
366   this->counter_ = new_counter;
367   this->ptr_ = rhs.ptr_;
368 }
369 
370 template <class X, class ACE_LOCK> inline bool
371 ACE_Weak_Bound_Ptr<X, ACE_LOCK>::operator== (const ACE_Weak_Bound_Ptr<X, ACE_LOCK> &r) const
372 {
373   // A weak pointer must behave as though it is automatically set to null
374   // if the underlying object has been deleted.
375   if (COUNTER::object_was_deleted (this->counter_))
376     return r.ptr_ == 0;
377 
378   return this->ptr_ == r.ptr_;
379 }
380 
381 template <class X, class ACE_LOCK> inline bool
382 ACE_Weak_Bound_Ptr<X, ACE_LOCK>::operator== (const ACE_Strong_Bound_Ptr<X, ACE_LOCK> &r) const
383 {
384   // A weak pointer must behave as though it is automatically set to null
385   // if the underlying object has been deleted.
386   if (COUNTER::object_was_deleted (this->counter_))
387     return r.ptr_ == 0;
388 
389   return this->ptr_ == r.ptr_;
390 }
391 
392 template <class X, class ACE_LOCK> inline bool
393 ACE_Weak_Bound_Ptr<X, ACE_LOCK>::operator== (X *p) const
394 {
395   // A weak pointer must behave as though it is automatically set to null
396   // if the underlying object has been deleted.
397   if (COUNTER::object_was_deleted (this->counter_))
398     return p == 0;
399 
400   return this->ptr_ == p;
401 }
402 
403 template <class X, class ACE_LOCK> inline bool
404 ACE_Weak_Bound_Ptr<X, ACE_LOCK>::operator!= (const ACE_Weak_Bound_Ptr<X, ACE_LOCK> &r) const
405 {
406   // A weak pointer must behave as though it is automatically set to null
407   // if the underlying object has been deleted.
408   if (COUNTER::object_was_deleted (this->counter_))
409     return r.ptr_ != 0;
410 
411   return this->ptr_ != r.ptr_;
412 }
413 
414 template <class X, class ACE_LOCK> inline bool
415 ACE_Weak_Bound_Ptr<X, ACE_LOCK>::operator!= (const ACE_Strong_Bound_Ptr<X, ACE_LOCK> &r) const
416 {
417   // A weak pointer must behave as though it is automatically set to null
418   // if the underlying object has been deleted.
419   if (COUNTER::object_was_deleted (this->counter_))
420     return r.ptr_ != 0;
421 
422   return this->ptr_ != r.ptr_;
423 }
424 
425 template <class X, class ACE_LOCK> inline bool
426 ACE_Weak_Bound_Ptr<X, ACE_LOCK>::operator!= (X *p) const
427 {
428   // A weak pointer must behave as though it is automatically set to null
429   // if the underlying object has been deleted.
430   if (COUNTER::object_was_deleted (this->counter_))
431     return p != 0;
432 
433   return this->ptr_ != p;
434 }
435 
436 template <class X, class ACE_LOCK> inline ACE_Strong_Bound_Ptr<X, ACE_LOCK>
437 ACE_Weak_Bound_Ptr<X, ACE_LOCK>::operator-> (void) const
438 {
439   return ACE_Strong_Bound_Ptr<X, ACE_LOCK> (*this);
440 }
441 
442 template <class X, class ACE_LOCK> inline ACE_Strong_Bound_Ptr<X, ACE_LOCK>
443 ACE_Weak_Bound_Ptr<X, ACE_LOCK>::strong (void) const
444 {
445   return ACE_Strong_Bound_Ptr<X, ACE_LOCK> (*this);
446 }
447 
448 template <class X, class ACE_LOCK> inline X*
449 ACE_Weak_Bound_Ptr<X, ACE_LOCK>::unsafe_get (void) const
450 {
451   // We do not check if the object has been deleted, since this operation
452   // is defined to be unsafe!
453   return this->ptr_;
454 }
455 
456 template <class X, class ACE_LOCK> inline bool
457 ACE_Weak_Bound_Ptr<X, ACE_LOCK>::null (void) const
458 {
459   // A weak pointer must behave as though it is automatically set to null
460   // if the underlying object has been deleted.
461   if (COUNTER::object_was_deleted (this->counter_))
462     return true;
463 
464   return this->ptr_ == 0;
465 }
466 
467 template<class X, class ACE_LOCK> inline void
468 ACE_Weak_Bound_Ptr<X, ACE_LOCK>::reset (X *p)
469 {
470   COUNTER *old_counter = this->counter_;
471   this->counter_ = COUNTER::create_weak ();
472   this->ptr_ = p;
473   COUNTER::detach_weak (old_counter);
474 }
475 
476 template<class X, class ACE_LOCK> inline long
477 ACE_Weak_Bound_Ptr<X, ACE_LOCK>::add_ref ()
478 {
479   return COUNTER::attach_strong (counter_);
480 }
481 
482 template<class X, class ACE_LOCK> inline long
483 ACE_Weak_Bound_Ptr<X, ACE_LOCK>::remove_ref ()
484 {
485   long new_obj_ref_count = COUNTER::detach_strong (counter_);
486   if (new_obj_ref_count == 0)
487     {
488       delete this->ptr_;
489       this->ptr_ = 0;
490     }
491   return new_obj_ref_count;
492 }
493 
494 ACE_END_VERSIONED_NAMESPACE_DECL

 

posted @ 2015-06-03 23:37  YipWingTim  阅读(303)  评论(0编辑  收藏  举报