zoukankan      html  css  js  c++  java
  • 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
  • 相关阅读:
    经典的笔试题python操作数据库和python设计模式【多测师_王sir】
    上证所python笔试题【多测师_王sir】
    银行移动消费信贷业务梳理【多测师_王sir】
    查看log.txt 日志文件中包含关键字x123或者x124的行,以及该行前后10行内容,并输出到out.txt中【多测师_王sir】【Linux题目】
    文件权限设置
    windows OpenSSH WARNING: UNPROTECTED PRIVATE KEY FILE!
    vue对象合并
    elk安装配置
    ElasticSearch
    Elastic Search之Search API(Query DSL)、字段类查询、复合查询
  • 原文地址:https://www.cnblogs.com/YipWingTim/p/4550640.html
Copyright © 2011-2022 走看看