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