zoukankan      html  css  js  c++  java
  • Android指针管理:RefBase,SP,WP (二)

    (1)在Android中,RefBase结合了sp和wp,实现了一套通过引用计数的方法来控制对象声明周期的方法。

    RefBase的定义在/frameworks/base/include/utils/RefBase.h,实现在/frameworks/base/libs/utils/RefBase.cpp。
    wp的定义在/frameworks/base/include/utils/RefBase.h,
    sp的定义在/frameworks/base/include/utils/StrongPointer.h中。

    (2)weakref_impl是weakref_type 的子类

    android_atomic_dec(&mCount) == 1  mCount减1,但是返回的是mCount减1之前的值。如果返回1,表示这次减过之后引用计数就是0了,就把对象delete掉。 

    android_atomic_inc(&impl->mStrong)  mCount加1,但是返回的是mCount加1之前的值。

    android_atomic_add(-INITIAL_STRONG_VALUE, &impl->mStrong);  加一个数,在此加的是(-INITIAL_STRONG_VALUE)

    android_atomic_cmpxchg(curCount, curCount+1, &impl->mStrong) 表示如果impl->mStrong的值为curCount,则把impl->mString的值改为curCount+1

    (3)对象声明周期的控制
    enum {
        OBJECT_LIFETIME_STRONG  = 0x0000,
        OBJECT_LIFETIME_WEAK    = 0x0001,
        OBJECT_LIFETIME_MASK    = 0x0001
    };

    void    extendObjectLifetime(int32_t mode);

    RefBase中,声明了一个枚举和extendObjectLifetime函数,来控制对象的生命周期。
    void RefBase::extendObjectLifetime(int32_t mode)
    {
        android_atomic_or(mode, &mRefs->mFlags);  // 用mode给weakref_impl的mFlags赋值     mFlags只在这一个地方赋值
    }

    (4)

    incStrong中, 将强引用数与弱引用数同时 +1

    decStrong中,将强引用数与弱引用数同时 -1

    incWeak中,只有弱引用数 +1

    decWeak中,只有弱引用数 -1

    (5)

    weakref_impl.mFlag == OBJECT_LIFETIME_STRONG时:
        强引用计数来控制对象的生命周期,弱引用对象控制weakref_impl的生命周期。
        强引用为0,对象被delete;弱引用为0时,weakref_impl被delete。
        记住:使用wp时,要有sp生成,否则可能会引起segment fault。
    weakref_impl.mFlag == OBJECT_LIFETIME_WEAK时:
        由弱引用来控制对象和weakref_impl的生命周期。
        强引用为0无作用,弱引用为0时,对象和weakref_impl被同时delete。

     (6)

    void RefBase::incStrong(const void* id) const
    {
        weakref_impl* const refs = mRefs;
        refs->incWeak(id);
        
        refs->addStrongRef(id);
        //refs->mStrong的值+1,但是返回的c是+1之前的值   
        const int32_t c = android_atomic_inc(&refs->mStrong);    
        ALOG_ASSERT(c > 0, "incStrong() called on %p after last strong ref", refs);
    #if PRINT_REFS
        ALOGD("incStrong of %p from %p: cnt=%d
    ", this, id, c);
    #endif
        if (c != INITIAL_STRONG_VALUE)  {    //+1之前不是INITAL_STRONG_VALUE,返回
            return;
        }
    
        //refs->mStrong=  INITIAL_STRONG_VALUE + 1 - INITIAL_STRONG_VALUE = 1 最终为1
        android_atomic_add(-INITIAL_STRONG_VALUE, &refs->mStrong);
        refs->mBase->onFirstRef();
    }

    第一次创建强引用会回调RefBase的onFirstRef()方法,这个方法很重要,派生类可以重载次方法,做一些初始化操作。在audio system中,很多类重载此方法!!!

    RefBase.h 源文件

      1 #ifndef ANDROID_REF_BASE_H
      2 #define ANDROID_REF_BASE_H
      3 
      4 #include <cutils/atomic.h>
      5 
      6 #include <stdint.h>
      7 #include <sys/types.h>
      8 #include <stdlib.h>
      9 #include <string.h>
     10 
     11 #include <utils/StrongPointer.h>
     12 #include <utils/TypeHelpers.h>
     13 
     14 // ---------------------------------------------------------------------------
     15 namespace android {
     16 
     17 class TextOutput;
     18 TextOutput& printWeakPointer(TextOutput& to, const void* val);
     19 
     20 // ---------------------------------------------------------------------------
     21 
     22 #define COMPARE_WEAK(_op_)                                      
     23 inline bool operator _op_ (const sp<T>& o) const {              
     24     return m_ptr _op_ o.m_ptr;                                  
     25 }                                                               
     26 inline bool operator _op_ (const T* o) const {                  
     27     return m_ptr _op_ o;                                        
     28 }                                                               
     29 template<typename U>                                            
     30 inline bool operator _op_ (const sp<U>& o) const {              
     31     return m_ptr _op_ o.m_ptr;                                  
     32 }                                                               
     33 template<typename U>                                            
     34 inline bool operator _op_ (const U* o) const {                  
     35     return m_ptr _op_ o;                                        
     36 }
     37 
     38 // ---------------------------------------------------------------------------
     39 
     40 class ReferenceRenamer {
     41 protected:
     42     // destructor is purposedly not virtual so we avoid code overhead from
     43     // subclasses; we have to make it protected to guarantee that it
     44     // cannot be called from this base class (and to make strict compilers
     45     // happy).
     46     ~ReferenceRenamer() { }
     47 public:
     48     virtual void operator()(size_t i) const = 0;
     49 };
     50 
     51 // ---------------------------------------------------------------------------
     52 
     53 class RefBase
     54 {
     55 public:
     56             void            incStrong(const void* id) const;
     57             void            decStrong(const void* id) const;
     58     
     59             void            forceIncStrong(const void* id) const;
     60 
     61             //! DEBUGGING ONLY: Get current strong ref count.
     62             int32_t         getStrongCount() const;
     63 
     64     class weakref_type                      
     65     {
     66     public:
     67         RefBase*            refBase() const;
     68         
     69         void                incWeak(const void* id);
     70         void                decWeak(const void* id);
     71         
     72         // acquires a strong reference if there is already one.
     73         bool                attemptIncStrong(const void* id);
     74         
     75         // acquires a weak reference if there is already one.
     76         // This is not always safe. see ProcessState.cpp and BpBinder.cpp
     77         // for proper use.
     78         bool                attemptIncWeak(const void* id);
     79 
     80         //! DEBUGGING ONLY: Get current weak ref count.
     81         int32_t             getWeakCount() const;
     82 
     83         //! DEBUGGING ONLY: Print references held on object.
     84         void                printRefs() const;
     85 
     86         //! DEBUGGING ONLY: Enable tracking for this object.
     87         // enable -- enable/disable tracking
     88         // retain -- when tracking is enable, if true, then we save a stack trace
     89         //           for each reference and dereference; when retain == false, we
     90         //           match up references and dereferences and keep only the 
     91         //           outstanding ones.
     92         
     93         void                trackMe(bool enable, bool retain);
     94     };
     95     
     96             weakref_type*   createWeak(const void* id) const;
     97             
     98             weakref_type*   getWeakRefs() const;
     99 
    100             //! DEBUGGING ONLY: Print references held on object.
    101     inline  void            printRefs() const { getWeakRefs()->printRefs(); }
    102 
    103             //! DEBUGGING ONLY: Enable tracking of object.
    104     inline  void            trackMe(bool enable, bool retain)
    105     { 
    106         getWeakRefs()->trackMe(enable, retain); 
    107     }
    108 
    109     typedef RefBase basetype;
    110 
    111 protected:
    112                             RefBase();
    113     virtual                 ~RefBase();
    114     
    115     //! Flags for extendObjectLifetime()
    116     enum {
    117         OBJECT_LIFETIME_STRONG  = 0x0000,
    118         OBJECT_LIFETIME_WEAK    = 0x0001,
    119         OBJECT_LIFETIME_MASK    = 0x0001
    120     };
    121     
    122             void            extendObjectLifetime(int32_t mode);
    123             
    124     //! Flags for onIncStrongAttempted()
    125     enum {
    126         FIRST_INC_STRONG = 0x0001
    127     };
    128     
    129     virtual void            onFirstRef();
    130     virtual void            onLastStrongRef(const void* id);
    131     virtual bool            onIncStrongAttempted(uint32_t flags, const void* id);
    132     virtual void            onLastWeakRef(const void* id);
    133 
    134 private:
    135     friend class weakref_type;
    136     class weakref_impl;
    137     
    138                             RefBase(const RefBase& o);
    139             RefBase&        operator=(const RefBase& o);
    140 
    141 private:
    142     friend class ReferenceMover;
    143 
    144     static void renameRefs(size_t n, const ReferenceRenamer& renamer);
    145 
    146     static void renameRefId(weakref_type* ref,
    147             const void* old_id, const void* new_id);
    148 
    149     static void renameRefId(RefBase* ref,
    150             const void* old_id, const void* new_id);
    151 
    152         weakref_impl* const mRefs;
    153 };
    154 
    155 // ---------------------------------------------------------------------------
    156 
    157 template <class T>
    158 class LightRefBase
    159 {
    160 public:
    161     inline LightRefBase() : mCount(0) { }
    162     inline void incStrong(__attribute__((unused)) const void* id) const {
    163         android_atomic_inc(&mCount);
    164     }
    165     inline void decStrong(__attribute__((unused)) const void* id) const {
    166         if (android_atomic_dec(&mCount) == 1) {
    167             delete static_cast<const T*>(this);
    168         }
    169     }
    170     //! DEBUGGING ONLY: Get current strong ref count.
    171     inline int32_t getStrongCount() const {
    172         return mCount;
    173     }
    174 
    175     typedef LightRefBase<T> basetype;
    176 
    177 protected:
    178     inline ~LightRefBase() { }
    179 
    180 private:
    181     friend class ReferenceMover;
    182     inline static void renameRefs(size_t n, const ReferenceRenamer& renamer) { }
    183     inline static void renameRefId(T* ref,
    184             const void* old_id, const void* new_id) { }
    185 
    186 private:
    187     mutable volatile int32_t mCount;
    188 };
    189 
    190 // ---------------------------------------------------------------------------
    191 
    192 template <typename T>
    193 class wp
    194 {
    195 public:
    196     typedef typename RefBase::weakref_type weakref_type;
    197     
    198     inline wp() : m_ptr(0) { }
    199 
    200     wp(T* other);
    201     wp(const wp<T>& other);
    202     wp(const sp<T>& other);
    203     template<typename U> wp(U* other);
    204     template<typename U> wp(const sp<U>& other);
    205     template<typename U> wp(const wp<U>& other);
    206 
    207     ~wp();
    208     
    209     // Assignment
    210 
    211     wp& operator = (T* other);
    212     wp& operator = (const wp<T>& other);
    213     wp& operator = (const sp<T>& other);
    214     
    215     template<typename U> wp& operator = (U* other);
    216     template<typename U> wp& operator = (const wp<U>& other);
    217     template<typename U> wp& operator = (const sp<U>& other);
    218     
    219     void set_object_and_refs(T* other, weakref_type* refs);
    220 
    221     // promotion to sp
    222     
    223     sp<T> promote() const;
    224 
    225     // Reset
    226     
    227     void clear();
    228 
    229     // Accessors
    230     
    231     inline  weakref_type* get_refs() const { return m_refs; }
    232     
    233     inline  T* unsafe_get() const { return m_ptr; }
    234 
    235     // Operators
    236 
    237     COMPARE_WEAK(==)
    238     COMPARE_WEAK(!=)
    239     COMPARE_WEAK(>)
    240     COMPARE_WEAK(<)
    241     COMPARE_WEAK(<=)
    242     COMPARE_WEAK(>=)
    243 
    244     inline bool operator == (const wp<T>& o) const {
    245         return (m_ptr == o.m_ptr) && (m_refs == o.m_refs);
    246     }
    247     template<typename U>
    248     inline bool operator == (const wp<U>& o) const {
    249         return m_ptr == o.m_ptr;
    250     }
    251 
    252     inline bool operator > (const wp<T>& o) const {
    253         return (m_ptr == o.m_ptr) ? (m_refs > o.m_refs) : (m_ptr > o.m_ptr);
    254     }
    255     template<typename U>
    256     inline bool operator > (const wp<U>& o) const {
    257         return (m_ptr == o.m_ptr) ? (m_refs > o.m_refs) : (m_ptr > o.m_ptr);
    258     }
    259 
    260     inline bool operator < (const wp<T>& o) const {
    261         return (m_ptr == o.m_ptr) ? (m_refs < o.m_refs) : (m_ptr < o.m_ptr);
    262     }
    263     template<typename U>
    264     inline bool operator < (const wp<U>& o) const {
    265         return (m_ptr == o.m_ptr) ? (m_refs < o.m_refs) : (m_ptr < o.m_ptr);
    266     }
    267                          inline bool operator != (const wp<T>& o) const { return m_refs != o.m_refs; }
    268     template<typename U> inline bool operator != (const wp<U>& o) const { return !operator == (o); }
    269                          inline bool operator <= (const wp<T>& o) const { return !operator > (o); }
    270     template<typename U> inline bool operator <= (const wp<U>& o) const { return !operator > (o); }
    271                          inline bool operator >= (const wp<T>& o) const { return !operator < (o); }
    272     template<typename U> inline bool operator >= (const wp<U>& o) const { return !operator < (o); }
    273 
    274 private:
    275     template<typename Y> friend class sp;
    276     template<typename Y> friend class wp;
    277 
    278     T*              m_ptr;
    279     weakref_type*   m_refs;
    280 };
    281 
    282 template <typename T>
    283 TextOutput& operator<<(TextOutput& to, const wp<T>& val);
    284 
    285 #undef COMPARE_WEAK
    286 
    287 // ---------------------------------------------------------------------------
    288 // No user serviceable parts below here.
    289 
    290 template<typename T>
    291 wp<T>::wp(T* other)
    292     : m_ptr(other)
    293 {
    294     if (other) m_refs = other->createWeak(this);
    295 }
    296 
    297 template<typename T>
    298 wp<T>::wp(const wp<T>& other)
    299     : m_ptr(other.m_ptr), m_refs(other.m_refs)
    300 {
    301     if (m_ptr) m_refs->incWeak(this);
    302 }
    303 
    304 template<typename T>
    305 wp<T>::wp(const sp<T>& other)
    306     : m_ptr(other.m_ptr)
    307 {
    308     if (m_ptr) {
    309         m_refs = m_ptr->createWeak(this);
    310     }
    311 }
    312 
    313 template<typename T> template<typename U>
    314 wp<T>::wp(U* other)
    315     : m_ptr(other)
    316 {
    317     if (other) m_refs = other->createWeak(this);
    318 }
    319 
    320 template<typename T> template<typename U>
    321 wp<T>::wp(const wp<U>& other)
    322     : m_ptr(other.m_ptr)
    323 {
    324     if (m_ptr) {
    325         m_refs = other.m_refs;
    326         m_refs->incWeak(this);
    327     }
    328 }
    329 
    330 template<typename T> template<typename U>
    331 wp<T>::wp(const sp<U>& other)
    332     : m_ptr(other.m_ptr)
    333 {
    334     if (m_ptr) {
    335         m_refs = m_ptr->createWeak(this);
    336     }
    337 }
    338 
    339 template<typename T>
    340 wp<T>::~wp()
    341 {
    342     if (m_ptr) m_refs->decWeak(this);
    343 }
    344 
    345 template<typename T>
    346 wp<T>& wp<T>::operator = (T* other)
    347 {
    348     weakref_type* newRefs =
    349         other ? other->createWeak(this) : 0;
    350     if (m_ptr) m_refs->decWeak(this);
    351     m_ptr = other;
    352     m_refs = newRefs;
    353     return *this;
    354 }
    355 
    356 template<typename T>
    357 wp<T>& wp<T>::operator = (const wp<T>& other)
    358 {
    359     weakref_type* otherRefs(other.m_refs);
    360     T* otherPtr(other.m_ptr);
    361     if (otherPtr) otherRefs->incWeak(this);
    362     if (m_ptr) m_refs->decWeak(this);
    363     m_ptr = otherPtr;
    364     m_refs = otherRefs;
    365     return *this;
    366 }
    367 
    368 template<typename T>
    369 wp<T>& wp<T>::operator = (const sp<T>& other)
    370 {
    371     weakref_type* newRefs =
    372         other != NULL ? other->createWeak(this) : 0;
    373     T* otherPtr(other.m_ptr);
    374     if (m_ptr) m_refs->decWeak(this);
    375     m_ptr = otherPtr;
    376     m_refs = newRefs;
    377     return *this;
    378 }
    379 
    380 template<typename T> template<typename U>
    381 wp<T>& wp<T>::operator = (U* other)
    382 {
    383     weakref_type* newRefs =
    384         other ? other->createWeak(this) : 0;
    385     if (m_ptr) m_refs->decWeak(this);
    386     m_ptr = other;
    387     m_refs = newRefs;
    388     return *this;
    389 }
    390 
    391 template<typename T> template<typename U>
    392 wp<T>& wp<T>::operator = (const wp<U>& other)
    393 {
    394     weakref_type* otherRefs(other.m_refs);
    395     U* otherPtr(other.m_ptr);
    396     if (otherPtr) otherRefs->incWeak(this);
    397     if (m_ptr) m_refs->decWeak(this);
    398     m_ptr = otherPtr;
    399     m_refs = otherRefs;
    400     return *this;
    401 }
    402 
    403 template<typename T> template<typename U>
    404 wp<T>& wp<T>::operator = (const sp<U>& other)
    405 {
    406     weakref_type* newRefs =
    407         other != NULL ? other->createWeak(this) : 0;
    408     U* otherPtr(other.m_ptr);
    409     if (m_ptr) m_refs->decWeak(this);
    410     m_ptr = otherPtr;
    411     m_refs = newRefs;
    412     return *this;
    413 }
    414 
    415 template<typename T>
    416 void wp<T>::set_object_and_refs(T* other, weakref_type* refs)
    417 {
    418     if (other) refs->incWeak(this);
    419     if (m_ptr) m_refs->decWeak(this);
    420     m_ptr = other;
    421     m_refs = refs;
    422 }
    423 
    424 template<typename T>
    425 sp<T> wp<T>::promote() const
    426 {
    427     sp<T> result;
    428     if (m_ptr && m_refs->attemptIncStrong(&result)) {
    429         result.set_pointer(m_ptr);
    430     }
    431     return result;
    432 }
    433 
    434 template<typename T>
    435 void wp<T>::clear()
    436 {
    437     if (m_ptr) {
    438         m_refs->decWeak(this);
    439         m_ptr = 0;
    440     }
    441 }
    442 
    443 template <typename T>
    444 inline TextOutput& operator<<(TextOutput& to, const wp<T>& val)
    445 {
    446     return printWeakPointer(to, val.unsafe_get());
    447 }
    448 
    449 // ---------------------------------------------------------------------------
    450 
    451 // this class just serves as a namespace so TYPE::moveReferences can stay
    452 // private.
    453 class ReferenceMover {
    454 public:
    455     // it would be nice if we could make sure no extra code is generated
    456     // for sp<TYPE> or wp<TYPE> when TYPE is a descendant of RefBase:
    457     // Using a sp<RefBase> override doesn't work; it's a bit like we wanted
    458     // a template<typename TYPE inherits RefBase> template...
    459 
    460     template<typename TYPE> static inline
    461     void move_references(sp<TYPE>* d, sp<TYPE> const* s, size_t n) {
    462 
    463         class Renamer : public ReferenceRenamer {
    464             sp<TYPE>* d;
    465             sp<TYPE> const* s;
    466             virtual void operator()(size_t i) const {
    467                 // The id are known to be the sp<>'s this pointer
    468                 TYPE::renameRefId(d[i].get(), &s[i], &d[i]);
    469             }
    470         public:
    471             Renamer(sp<TYPE>* d, sp<TYPE> const* s) : s(s), d(d) { }
    472         };
    473 
    474         memmove(d, s, n*sizeof(sp<TYPE>));
    475         TYPE::renameRefs(n, Renamer(d, s));
    476     }
    477 
    478 
    479     template<typename TYPE> static inline
    480     void move_references(wp<TYPE>* d, wp<TYPE> const* s, size_t n) {
    481 
    482         class Renamer : public ReferenceRenamer {
    483             wp<TYPE>* d;
    484             wp<TYPE> const* s;
    485             virtual void operator()(size_t i) const {
    486                 // The id are known to be the wp<>'s this pointer
    487                 TYPE::renameRefId(d[i].get_refs(), &s[i], &d[i]);
    488             }
    489         public:
    490             Renamer(wp<TYPE>* d, wp<TYPE> const* s) : s(s), d(d) { }
    491         };
    492 
    493         memmove(d, s, n*sizeof(wp<TYPE>));
    494         TYPE::renameRefs(n, Renamer(d, s));
    495     }
    496 };
    497 
    498 // specialization for moving sp<> and wp<> types.
    499 // these are used by the [Sorted|Keyed]Vector<> implementations
    500 // sp<> and wp<> need to be handled specially, because they do not
    501 // have trivial copy operation in the general case (see RefBase.cpp
    502 // when DEBUG ops are enabled), but can be implemented very
    503 // efficiently in most cases.
    504 
    505 template<typename TYPE> inline
    506 void move_forward_type(sp<TYPE>* d, sp<TYPE> const* s, size_t n) {
    507     ReferenceMover::move_references(d, s, n);
    508 }
    509 
    510 template<typename TYPE> inline
    511 void move_backward_type(sp<TYPE>* d, sp<TYPE> const* s, size_t n) {
    512     ReferenceMover::move_references(d, s, n);
    513 }
    514 
    515 template<typename TYPE> inline
    516 void move_forward_type(wp<TYPE>* d, wp<TYPE> const* s, size_t n) {
    517     ReferenceMover::move_references(d, s, n);
    518 }
    519 
    520 template<typename TYPE> inline
    521 void move_backward_type(wp<TYPE>* d, wp<TYPE> const* s, size_t n) {
    522     ReferenceMover::move_references(d, s, n);
    523 }
    524 
    525 
    526 }; // namespace android
    527 
    528 // ---------------------------------------------------------------------------
    529 
    530 #endif // ANDROID_REF_BASE_H
    View Code

    去掉Debug和其他信息,简化之后的RefBase.h:

    类RefBase:

     1 class RefBase
     2 {
     3 public:
     4             void            incStrong(const void* id) const;
     5             void            decStrong(const void* id) const;
     6     
     7             void            forceIncStrong(const void* id) const;
     8 
     9             //! DEBUGGING ONLY: Get current strong ref count.
    10             int32_t         getStrongCount() const;
    11     
    12             weakref_type*   createWeak(const void* id) const;
    13             
    14             weakref_type*   getWeakRefs() const;
    15 
    16     typedef RefBase basetype;
    17 
    18 protected:
    19                             RefBase();
    20     virtual                 ~RefBase();
    21     
    22     //! Flags for extendObjectLifetime()
    23     enum {
    24         OBJECT_LIFETIME_STRONG  = 0x0000,
    25         OBJECT_LIFETIME_WEAK    = 0x0001,
    26         OBJECT_LIFETIME_MASK    = 0x0001
    27     };
    28     
    29             void            extendObjectLifetime(int32_t mode);
    30             
    31     //! Flags for onIncStrongAttempted()
    32     enum {
    33         FIRST_INC_STRONG = 0x0001
    34     };
    35     
    36     virtual void            onFirstRef();
    37     virtual void            onLastStrongRef(const void* id);
    38     virtual bool            onIncStrongAttempted(uint32_t flags, const void* id);
    39     virtual void            onLastWeakRef(const void* id);
    40 
    41 private:
    42     friend class weakref_type;
    43     class weakref_impl;
    44     
    45                             RefBase(const RefBase& o);
    46             RefBase&        operator=(const RefBase& o);
    47 
    48 };
    View Code

    类LightRefBase:

     1 template <class T>
     2 class LightRefBase
     3 {
     4 public:
     5     inline LightRefBase() : mCount(0) { }
     6     inline void incStrong(__attribute__((unused)) const void* id) const {
     7         android_atomic_inc(&mCount);
     8     }
     9     inline void decStrong(__attribute__((unused)) const void* id) const {
    10         if (android_atomic_dec(&mCount) == 1) {
    11             delete static_cast<const T*>(this);
    12         }
    13     }
    14     //! DEBUGGING ONLY: Get current strong ref count.
    15     inline int32_t getStrongCount() const {
    16         return mCount;
    17     }
    18 
    19     typedef LightRefBase<T> basetype;
    20 
    21 protected:
    22     inline ~LightRefBase() { }
    23 
    24 private:
    25     friend class ReferenceMover;
    26     inline static void renameRefs(size_t n, const ReferenceRenamer& renamer) { }
    27     inline static void renameRefId(T* ref,
    28             const void* old_id, const void* new_id) { }
    29 
    30 private:
    31     mutable volatile int32_t mCount;
    32 };
    View Code

    类wp:

     1 template <typename T>
     2 class wp
     3 {
     4 public:
     5     typedef typename RefBase::weakref_type weakref_type;
     6     
     7     inline wp() : m_ptr(0) { }
     8 
     9     wp(T* other);
    10     wp(const wp<T>& other);
    11     wp(const sp<T>& other);
    12     template<typename U> wp(U* other);
    13     template<typename U> wp(const sp<U>& other);
    14     template<typename U> wp(const wp<U>& other);
    15 
    16     ~wp();
    17     
    18     // Assignment
    19 
    20     wp& operator = (T* other);
    21     wp& operator = (const wp<T>& other);
    22     wp& operator = (const sp<T>& other);
    23     
    24     template<typename U> wp& operator = (U* other);
    25     template<typename U> wp& operator = (const wp<U>& other);
    26     template<typename U> wp& operator = (const sp<U>& other);
    27     
    28     void set_object_and_refs(T* other, weakref_type* refs);
    29 
    30     // promotion to sp
    31     
    32     sp<T> promote() const;
    33 
    34     // Reset
    35     
    36     void clear();
    37 
    38     // Accessors
    39     
    40     inline  weakref_type* get_refs() const { return m_refs; }
    41     
    42     inline  T* unsafe_get() const { return m_ptr; }
    43 
    44     // Operators
    45 
    46     COMPARE_WEAK(==)
    47     COMPARE_WEAK(!=)
    48     COMPARE_WEAK(>)
    49     COMPARE_WEAK(<)
    50     COMPARE_WEAK(<=)
    51     COMPARE_WEAK(>=)
    52 
    53     inline bool operator == (const wp<T>& o) const {
    54         return (m_ptr == o.m_ptr) && (m_refs == o.m_refs);
    55     }
    56     template<typename U>
    57     inline bool operator == (const wp<U>& o) const {
    58         return m_ptr == o.m_ptr;
    59     }
    60 
    61     inline bool operator > (const wp<T>& o) const {
    62         return (m_ptr == o.m_ptr) ? (m_refs > o.m_refs) : (m_ptr > o.m_ptr);
    63     }
    64     template<typename U>
    65     inline bool operator > (const wp<U>& o) const {
    66         return (m_ptr == o.m_ptr) ? (m_refs > o.m_refs) : (m_ptr > o.m_ptr);
    67     }
    68 
    69     inline bool operator < (const wp<T>& o) const {
    70         return (m_ptr == o.m_ptr) ? (m_refs < o.m_refs) : (m_ptr < o.m_ptr);
    71     }
    72     template<typename U>
    73     inline bool operator < (const wp<U>& o) const {
    74         return (m_ptr == o.m_ptr) ? (m_refs < o.m_refs) : (m_ptr < o.m_ptr);
    75     }
    76                          inline bool operator != (const wp<T>& o) const { return m_refs != o.m_refs; }
    77     template<typename U> inline bool operator != (const wp<U>& o) const { return !operator == (o); }
    78                          inline bool operator <= (const wp<T>& o) const { return !operator > (o); }
    79     template<typename U> inline bool operator <= (const wp<U>& o) const { return !operator > (o); }
    80                          inline bool operator >= (const wp<T>& o) const { return !operator < (o); }
    81     template<typename U> inline bool operator >= (const wp<U>& o) const { return !operator < (o); }
    82 
    83 private:
    84     template<typename Y> friend class sp;
    85     template<typename Y> friend class wp;
    86 
    87     T*              m_ptr;
    88     weakref_type*   m_refs;
    89 };
    View Code

    类wp函数实现:

      1 template<typename T>
      2 wp<T>::wp(T* other)
      3     : m_ptr(other)
      4 {
      5     if (other) m_refs = other->createWeak(this);
      6 }
      7 
      8 template<typename T>
      9 wp<T>::wp(const wp<T>& other)
     10     : m_ptr(other.m_ptr), m_refs(other.m_refs)
     11 {
     12     if (m_ptr) m_refs->incWeak(this);
     13 }
     14 
     15 template<typename T>
     16 wp<T>::wp(const sp<T>& other)
     17     : m_ptr(other.m_ptr)
     18 {
     19     if (m_ptr) {
     20         m_refs = m_ptr->createWeak(this);
     21     }
     22 }
     23 
     24 template<typename T> template<typename U>
     25 wp<T>::wp(U* other)
     26     : m_ptr(other)
     27 {
     28     if (other) m_refs = other->createWeak(this);
     29 }
     30 
     31 template<typename T> template<typename U>
     32 wp<T>::wp(const wp<U>& other)
     33     : m_ptr(other.m_ptr)
     34 {
     35     if (m_ptr) {
     36         m_refs = other.m_refs;
     37         m_refs->incWeak(this);
     38     }
     39 }
     40 
     41 template<typename T> template<typename U>
     42 wp<T>::wp(const sp<U>& other)
     43     : m_ptr(other.m_ptr)
     44 {
     45     if (m_ptr) {
     46         m_refs = m_ptr->createWeak(this);
     47     }
     48 }
     49 
     50 template<typename T>
     51 wp<T>::~wp()
     52 {
     53     if (m_ptr) m_refs->decWeak(this);
     54 }
     55 
     56 template<typename T>
     57 wp<T>& wp<T>::operator = (T* other)
     58 {
     59     weakref_type* newRefs =
     60         other ? other->createWeak(this) : 0;
     61     if (m_ptr) m_refs->decWeak(this);
     62     m_ptr = other;
     63     m_refs = newRefs;
     64     return *this;
     65 }
     66 
     67 template<typename T>
     68 wp<T>& wp<T>::operator = (const wp<T>& other)
     69 {
     70     weakref_type* otherRefs(other.m_refs);
     71     T* otherPtr(other.m_ptr);
     72     if (otherPtr) otherRefs->incWeak(this);
     73     if (m_ptr) m_refs->decWeak(this);
     74     m_ptr = otherPtr;
     75     m_refs = otherRefs;
     76     return *this;
     77 }
     78 
     79 template<typename T>
     80 wp<T>& wp<T>::operator = (const sp<T>& other)
     81 {
     82     weakref_type* newRefs =
     83         other != NULL ? other->createWeak(this) : 0;
     84     T* otherPtr(other.m_ptr);
     85     if (m_ptr) m_refs->decWeak(this);
     86     m_ptr = otherPtr;
     87     m_refs = newRefs;
     88     return *this;
     89 }
     90 
     91 template<typename T> template<typename U>
     92 wp<T>& wp<T>::operator = (U* other)
     93 {
     94     weakref_type* newRefs =
     95         other ? other->createWeak(this) : 0;
     96     if (m_ptr) m_refs->decWeak(this);
     97     m_ptr = other;
     98     m_refs = newRefs;
     99     return *this;
    100 }
    101 
    102 template<typename T> template<typename U>
    103 wp<T>& wp<T>::operator = (const wp<U>& other)
    104 {
    105     weakref_type* otherRefs(other.m_refs);
    106     U* otherPtr(other.m_ptr);
    107     if (otherPtr) otherRefs->incWeak(this);
    108     if (m_ptr) m_refs->decWeak(this);
    109     m_ptr = otherPtr;
    110     m_refs = otherRefs;
    111     return *this;
    112 }
    113 
    114 template<typename T> template<typename U>
    115 wp<T>& wp<T>::operator = (const sp<U>& other)
    116 {
    117     weakref_type* newRefs =
    118         other != NULL ? other->createWeak(this) : 0;
    119     U* otherPtr(other.m_ptr);
    120     if (m_ptr) m_refs->decWeak(this);
    121     m_ptr = otherPtr;
    122     m_refs = newRefs;
    123     return *this;
    124 }
    125 
    126 template<typename T>
    127 void wp<T>::set_object_and_refs(T* other, weakref_type* refs)
    128 {
    129     if (other) refs->incWeak(this);
    130     if (m_ptr) m_refs->decWeak(this);
    131     m_ptr = other;
    132     m_refs = refs;
    133 }
    134 
    135 template<typename T>
    136 sp<T> wp<T>::promote() const
    137 {
    138     sp<T> result;
    139     if (m_ptr && m_refs->attemptIncStrong(&result)) {
    140         result.set_pointer(m_ptr);
    141     }
    142     return result;
    143 }
    144 
    145 template<typename T>
    146 void wp<T>::clear()
    147 {
    148     if (m_ptr) {
    149         m_refs->decWeak(this);
    150         m_ptr = 0;
    151     }
    152 }
    View Code

    RefBase.cpp 源文件

    View Code

    简化之后的RefBase.cpp:

    继承自weakref_type的类weakref_impl:

     1 class RefBase::weakref_impl : public RefBase::weakref_type
     2 {
     3 public:
     4     volatile int32_t    mStrong;
     5     volatile int32_t    mWeak;
     6     RefBase* const      mBase;
     7     volatile int32_t    mFlags;
     8 
     9     weakref_impl(RefBase* base)
    10         : mStrong(INITIAL_STRONG_VALUE)
    11         , mWeak(0)
    12         , mBase(base)
    13         , mFlags(0)
    14     {
    15     }
    16 
    17     void addStrongRef(const void* /*id*/) { }
    18     void removeStrongRef(const void* /*id*/) { }
    19     void renameStrongRefId(const void* /*old_id*/, const void* /*new_id*/) { }
    20     void addWeakRef(const void* /*id*/) { }
    21     void removeWeakRef(const void* /*id*/) { }
    22     void renameWeakRefId(const void* /*old_id*/, const void* /*new_id*/) { }
    23     void printRefs() const { }
    24     void trackMe(bool, bool) { }
    25 
    26 };
    View Code

    RefBase类的函数实现:

      1 #define INITIAL_STRONG_VALUE (1<<28)
      2 
      3 
      4 void RefBase::incStrong(const void* id) const
      5 {
      6     weakref_impl* const refs = mRefs;
      7     refs->incWeak(id);
      8     
      9     refs->addStrongRef(id);
     10     const int32_t c = android_atomic_inc(&refs->mStrong);
     11     ALOG_ASSERT(c > 0, "incStrong() called on %p after last strong ref", refs);
     12 #if PRINT_REFS
     13     ALOGD("incStrong of %p from %p: cnt=%d
    ", this, id, c);
     14 #endif
     15     if (c != INITIAL_STRONG_VALUE)  {
     16         return;
     17     }
     18 
     19     android_atomic_add(-INITIAL_STRONG_VALUE, &refs->mStrong);
     20     refs->mBase->onFirstRef();
     21 }
     22 
     23 void RefBase::decStrong(const void* id) const
     24 {
     25     weakref_impl* const refs = mRefs;
     26     refs->removeStrongRef(id);
     27     const int32_t c = android_atomic_dec(&refs->mStrong);
     28 #if PRINT_REFS
     29     ALOGD("decStrong of %p from %p: cnt=%d
    ", this, id, c);
     30 #endif
     31     ALOG_ASSERT(c >= 1, "decStrong() called on %p too many times", refs);
     32     if (c == 1) {
     33         refs->mBase->onLastStrongRef(id);
     34         if ((refs->mFlags&OBJECT_LIFETIME_MASK) == OBJECT_LIFETIME_STRONG) {
     35             delete this;
     36         }
     37     }
     38     refs->decWeak(id);
     39 }
     40 
     41 void RefBase::forceIncStrong(const void* id) const
     42 {
     43     weakref_impl* const refs = mRefs;
     44     refs->incWeak(id);
     45     
     46     refs->addStrongRef(id);
     47     const int32_t c = android_atomic_inc(&refs->mStrong);
     48     ALOG_ASSERT(c >= 0, "forceIncStrong called on %p after ref count underflow",
     49                refs);
     50 #if PRINT_REFS
     51     ALOGD("forceIncStrong of %p from %p: cnt=%d
    ", this, id, c);
     52 #endif
     53 
     54     switch (c) {
     55     case INITIAL_STRONG_VALUE:
     56         android_atomic_add(-INITIAL_STRONG_VALUE, &refs->mStrong);
     57         // fall through...
     58     case 0:
     59         refs->mBase->onFirstRef();
     60     }
     61 }
     62 
     63 int32_t RefBase::getStrongCount() const
     64 {
     65     return mRefs->mStrong;
     66 }
     67 
     68 RefBase::weakref_type* RefBase::createWeak(const void* id) const
     69 {
     70     mRefs->incWeak(id);
     71     return mRefs;
     72 }
     73 
     74 RefBase::weakref_type* RefBase::getWeakRefs() const
     75 {
     76     return mRefs;
     77 }
     78 
     79 RefBase::RefBase()
     80     : mRefs(new weakref_impl(this))
     81 {
     82 }
     83 
     84 RefBase::~RefBase()
     85 {
     86     if (mRefs->mStrong == INITIAL_STRONG_VALUE) {
     87         // we never acquired a strong (and/or weak) reference on this object.
     88         delete mRefs;
     89     } else {
     90         // life-time of this object is extended to WEAK or FOREVER, in
     91         // which case weakref_impl doesn't out-live the object and we
     92         // can free it now.
     93         if ((mRefs->mFlags & OBJECT_LIFETIME_MASK) != OBJECT_LIFETIME_STRONG) {
     94             // It's possible that the weak count is not 0 if the object
     95             // re-acquired a weak reference in its destructor
     96             if (mRefs->mWeak == 0) {
     97                 delete mRefs;
     98             }
     99         }
    100     }
    101     // for debugging purposes, clear this.
    102     const_cast<weakref_impl*&>(mRefs) = NULL;
    103 }
    104 
    105 void RefBase::extendObjectLifetime(int32_t mode)
    106 {
    107     android_atomic_or(mode, &mRefs->mFlags);
    108 }
    109 
    110 void RefBase::onFirstRef()
    111 {
    112 }
    113 
    114 void RefBase::onLastStrongRef(const void* /*id*/)
    115 {
    116 }
    117 
    118 bool RefBase::onIncStrongAttempted(uint32_t flags, const void* id)
    119 {
    120     return (flags&FIRST_INC_STRONG) ? true : false;
    121 }
    122 
    123 void RefBase::onLastWeakRef(const void* /*id*/)
    124 {
    125 }
    View Code

      RefBase::weakref_type 类的函数实现:

      1 RefBase* RefBase::weakref_type::refBase() const
      2 {
      3     return static_cast<const weakref_impl*>(this)->mBase;
      4 }
      5 
      6 void RefBase::weakref_type::incWeak(const void* id)
      7 {
      8     weakref_impl* const impl = static_cast<weakref_impl*>(this);
      9     impl->addWeakRef(id);
     10     const int32_t c = android_atomic_inc(&impl->mWeak);
     11     ALOG_ASSERT(c >= 0, "incWeak called on %p after last weak ref", this);
     12 }
     13 
     14 
     15 void RefBase::weakref_type::decWeak(const void* id)
     16 {
     17     weakref_impl* const impl = static_cast<weakref_impl*>(this);
     18     impl->removeWeakRef(id);
     19     const int32_t c = android_atomic_dec(&impl->mWeak);
     20     ALOG_ASSERT(c >= 1, "decWeak called on %p too many times", this);
     21     if (c != 1) return;
     22 
     23     if ((impl->mFlags&OBJECT_LIFETIME_WEAK) == OBJECT_LIFETIME_STRONG) {
     24         // This is the regular lifetime case. The object is destroyed
     25         // when the last strong reference goes away. Since weakref_impl
     26         // outlive the object, it is not destroyed in the dtor, and
     27         // we'll have to do it here.
     28         if (impl->mStrong == INITIAL_STRONG_VALUE) {
     29             // Special case: we never had a strong reference, so we need to
     30             // destroy the object now.
     31             delete impl->mBase;
     32         } else {
     33             // ALOGV("Freeing refs %p of old RefBase %p
    ", this, impl->mBase);
     34             delete impl;
     35         }
     36     } else {
     37         // less common case: lifetime is OBJECT_LIFETIME_{WEAK|FOREVER}
     38         impl->mBase->onLastWeakRef(id);
     39         if ((impl->mFlags&OBJECT_LIFETIME_MASK) == OBJECT_LIFETIME_WEAK) {
     40             // this is the OBJECT_LIFETIME_WEAK case. The last weak-reference
     41             // is gone, we can destroy the object.
     42             delete impl->mBase;
     43         }
     44     }
     45 }
     46 
     47 bool RefBase::weakref_type::attemptIncStrong(const void* id)
     48 {
     49     incWeak(id);
     50     
     51     weakref_impl* const impl = static_cast<weakref_impl*>(this);
     52     int32_t curCount = impl->mStrong;
     53 
     54     ALOG_ASSERT(curCount >= 0,
     55             "attemptIncStrong called on %p after underflow", this);
     56 
     57     while (curCount > 0 && curCount != INITIAL_STRONG_VALUE) {
     58         // we're in the easy/common case of promoting a weak-reference
     59         // from an existing strong reference.
     60         if (android_atomic_cmpxchg(curCount, curCount+1, &impl->mStrong) == 0) {
     61             break;
     62         }
     63         // the strong count has changed on us, we need to re-assert our
     64         // situation.
     65         curCount = impl->mStrong;
     66     }
     67     
     68     if (curCount <= 0 || curCount == INITIAL_STRONG_VALUE) {
     69         // we're now in the harder case of either:
     70         // - there never was a strong reference on us
     71         // - or, all strong references have been released
     72         if ((impl->mFlags&OBJECT_LIFETIME_WEAK) == OBJECT_LIFETIME_STRONG) {
     73             // this object has a "normal" life-time, i.e.: it gets destroyed
     74             // when the last strong reference goes away
     75             if (curCount <= 0) {
     76                 // the last strong-reference got released, the object cannot
     77                 // be revived.
     78                 decWeak(id);
     79                 return false;
     80             }
     81 
     82             // here, curCount == INITIAL_STRONG_VALUE, which means
     83             // there never was a strong-reference, so we can try to
     84             // promote this object; we need to do that atomically.
     85             while (curCount > 0) {
     86                 if (android_atomic_cmpxchg(curCount, curCount + 1,
     87                         &impl->mStrong) == 0) {
     88                     break;
     89                 }
     90                 // the strong count has changed on us, we need to re-assert our
     91                 // situation (e.g.: another thread has inc/decStrong'ed us)
     92                 curCount = impl->mStrong;
     93             }
     94 
     95             if (curCount <= 0) {
     96                 // promote() failed, some other thread destroyed us in the
     97                 // meantime (i.e.: strong count reached zero).
     98                 decWeak(id);
     99                 return false;
    100             }
    101         } else {
    102             // this object has an "extended" life-time, i.e.: it can be
    103             // revived from a weak-reference only.
    104             // Ask the object's implementation if it agrees to be revived
    105             if (!impl->mBase->onIncStrongAttempted(FIRST_INC_STRONG, id)) {
    106                 // it didn't so give-up.
    107                 decWeak(id);
    108                 return false;
    109             }
    110             // grab a strong-reference, which is always safe due to the
    111             // extended life-time.
    112             curCount = android_atomic_inc(&impl->mStrong);
    113         }
    114 
    115         // If the strong reference count has already been incremented by
    116         // someone else, the implementor of onIncStrongAttempted() is holding
    117         // an unneeded reference.  So call onLastStrongRef() here to remove it.
    118         // (No, this is not pretty.)  Note that we MUST NOT do this if we
    119         // are in fact acquiring the first reference.
    120         if (curCount > 0 && curCount < INITIAL_STRONG_VALUE) {
    121             impl->mBase->onLastStrongRef(id);
    122         }
    123     }
    124     
    125     impl->addStrongRef(id);
    126 
    127 #if PRINT_REFS
    128     ALOGD("attemptIncStrong of %p from %p: cnt=%d
    ", this, id, curCount);
    129 #endif
    130 
    131     // now we need to fix-up the count if it was INITIAL_STRONG_VALUE
    132     // this must be done safely, i.e.: handle the case where several threads
    133     // were here in attemptIncStrong().
    134     curCount = impl->mStrong;
    135     while (curCount >= INITIAL_STRONG_VALUE) {
    136         ALOG_ASSERT(curCount > INITIAL_STRONG_VALUE,
    137                 "attemptIncStrong in %p underflowed to INITIAL_STRONG_VALUE",
    138                 this);
    139         if (android_atomic_cmpxchg(curCount, curCount-INITIAL_STRONG_VALUE,
    140                 &impl->mStrong) == 0) {
    141             break;
    142         }
    143         // the strong-count changed on us, we need to re-assert the situation,
    144         // for e.g.: it's possible the fix-up happened in another thread.
    145         curCount = impl->mStrong;
    146     }
    147 
    148     return true;
    149 }
    150 
    151 bool RefBase::weakref_type::attemptIncWeak(const void* id)
    152 {
    153     weakref_impl* const impl = static_cast<weakref_impl*>(this);
    154 
    155     int32_t curCount = impl->mWeak;
    156     ALOG_ASSERT(curCount >= 0, "attemptIncWeak called on %p after underflow",
    157                this);
    158     while (curCount > 0) {
    159         if (android_atomic_cmpxchg(curCount, curCount+1, &impl->mWeak) == 0) {
    160             break;
    161         }
    162         curCount = impl->mWeak;
    163     }
    164 
    165     if (curCount > 0) {
    166         impl->addWeakRef(id);
    167     }
    168 
    169     return curCount > 0;
    170 }
    171 
    172 int32_t RefBase::weakref_type::getWeakCount() const
    173 {
    174     return static_cast<const weakref_impl*>(this)->mWeak;
    175 }
    176 
    177 void RefBase::weakref_type::printRefs() const
    178 {
    179     static_cast<const weakref_impl*>(this)->printRefs();
    180 }
    181 
    182 void RefBase::weakref_type::trackMe(bool enable, bool retain)
    183 {
    184     static_cast<weakref_impl*>(this)->trackMe(enable, retain);
    185 }
    View Code

    sp类声明 (StrongPointer.h)

      1 /*
      2  * Copyright (C) 2005 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 #ifndef ANDROID_STRONG_POINTER_H
     18 #define ANDROID_STRONG_POINTER_H
     19 
     20 #include <cutils/atomic.h>
     21 
     22 #include <stdint.h>
     23 #include <sys/types.h>
     24 #include <stdlib.h>
     25 
     26 // ---------------------------------------------------------------------------
     27 namespace android {
     28 
     29 template<typename T> class wp;
     30 
     31 // ---------------------------------------------------------------------------
     32 
     33 #define COMPARE(_op_)                                           
     34 inline bool operator _op_ (const sp<T>& o) const {              
     35     return m_ptr _op_ o.m_ptr;                                  
     36 }                                                               
     37 inline bool operator _op_ (const T* o) const {                  
     38     return m_ptr _op_ o;                                        
     39 }                                                               
     40 template<typename U>                                            
     41 inline bool operator _op_ (const sp<U>& o) const {              
     42     return m_ptr _op_ o.m_ptr;                                  
     43 }                                                               
     44 template<typename U>                                            
     45 inline bool operator _op_ (const U* o) const {                  
     46     return m_ptr _op_ o;                                        
     47 }                                                               
     48 inline bool operator _op_ (const wp<T>& o) const {              
     49     return m_ptr _op_ o.m_ptr;                                  
     50 }                                                               
     51 template<typename U>                                            
     52 inline bool operator _op_ (const wp<U>& o) const {              
     53     return m_ptr _op_ o.m_ptr;                                  
     54 }
     55 
     56 // ---------------------------------------------------------------------------
     57 
     58 template<typename T>
     59 class sp {
     60 public:
     61     inline sp() : m_ptr(0) { }
     62 
     63     sp(T* other);
     64     sp(const sp<T>& other);
     65     template<typename U> sp(U* other);
     66     template<typename U> sp(const sp<U>& other);
     67 
     68     ~sp();
     69 
     70     // Assignment
     71 
     72     sp& operator = (T* other);
     73     sp& operator = (const sp<T>& other);
     74 
     75     template<typename U> sp& operator = (const sp<U>& other);
     76     template<typename U> sp& operator = (U* other);
     77 
     78     //! Special optimization for use by ProcessState (and nobody else).
     79     void force_set(T* other);
     80 
     81     // Reset
     82 
     83     void clear();
     84 
     85     // Accessors
     86 
     87     inline  T&      operator* () const  { return *m_ptr; }
     88     inline  T*      operator-> () const { return m_ptr;  }
     89     inline  T*      get() const         { return m_ptr; }
     90 
     91     // Operators
     92 
     93     COMPARE(==)
     94     COMPARE(!=)
     95     COMPARE(>)
     96     COMPARE(<)
     97     COMPARE(<=)
     98     COMPARE(>=)
     99 
    100 private:    
    101     template<typename Y> friend class sp;
    102     template<typename Y> friend class wp;
    103     void set_pointer(T* ptr);
    104     T* m_ptr;
    105 };
    106 
    107 #undef COMPARE
    108 
    109 // ---------------------------------------------------------------------------
    110 // No user serviceable parts below here.
    111 
    112 template<typename T>
    113 sp<T>::sp(T* other)
    114         : m_ptr(other) {
    115     if (other)
    116         other->incStrong(this);
    117 }
    118 
    119 template<typename T>
    120 sp<T>::sp(const sp<T>& other)
    121         : m_ptr(other.m_ptr) {
    122     if (m_ptr)
    123         m_ptr->incStrong(this);
    124 }
    125 
    126 template<typename T> template<typename U>
    127 sp<T>::sp(U* other)
    128         : m_ptr(other) {
    129     if (other)
    130         ((T*) other)->incStrong(this);
    131 }
    132 
    133 template<typename T> template<typename U>
    134 sp<T>::sp(const sp<U>& other)
    135         : m_ptr(other.m_ptr) {
    136     if (m_ptr)
    137         m_ptr->incStrong(this);
    138 }
    139 
    140 template<typename T>
    141 sp<T>::~sp() {
    142     if (m_ptr)
    143         m_ptr->decStrong(this);
    144 }
    145 
    146 template<typename T>
    147 sp<T>& sp<T>::operator =(const sp<T>& other) {
    148     T* otherPtr(other.m_ptr);
    149     if (otherPtr)
    150         otherPtr->incStrong(this);
    151     if (m_ptr)
    152         m_ptr->decStrong(this);
    153     m_ptr = otherPtr;
    154     return *this;
    155 }
    156 
    157 template<typename T>
    158 sp<T>& sp<T>::operator =(T* other) {
    159     if (other)
    160         other->incStrong(this);
    161     if (m_ptr)
    162         m_ptr->decStrong(this);
    163     m_ptr = other;
    164     return *this;
    165 }
    166 
    167 template<typename T> template<typename U>
    168 sp<T>& sp<T>::operator =(const sp<U>& other) {
    169     T* otherPtr(other.m_ptr);
    170     if (otherPtr)
    171         otherPtr->incStrong(this);
    172     if (m_ptr)
    173         m_ptr->decStrong(this);
    174     m_ptr = otherPtr;
    175     return *this;
    176 }
    177 
    178 template<typename T> template<typename U>
    179 sp<T>& sp<T>::operator =(U* other) {
    180     if (other)
    181         ((T*) other)->incStrong(this);
    182     if (m_ptr)
    183         m_ptr->decStrong(this);
    184     m_ptr = other;
    185     return *this;
    186 }
    187 
    188 template<typename T>
    189 void sp<T>::force_set(T* other) {
    190     other->forceIncStrong(this);
    191     m_ptr = other;
    192 }
    193 
    194 template<typename T>
    195 void sp<T>::clear() {
    196     if (m_ptr) {
    197         m_ptr->decStrong(this);
    198         m_ptr = 0;
    199     }
    200 }
    201 
    202 template<typename T>
    203 void sp<T>::set_pointer(T* ptr) {
    204     m_ptr = ptr;
    205 }
    206 
    207 }; // namespace android
    208 
    209 // ---------------------------------------------------------------------------
    210 
    211 #endif // ANDROID_STRONG_POINTER_H
    View Code
  • 相关阅读:
    UESTC 250 windy数 数位dp
    hdu 3555 bomb 数位dp
    hdu 2089 不要62 数位dp入门
    poj 3740 Easy Finding 精确匹配
    codeforces 589F. Gourmet and Banquet 二分+网络流
    hdu 3572 Escape 网络流
    hdu 3572 Task Schedule 网络流
    POJ 1823 Hotel 线段树
    2016年,机器学习和人工智能领域有什么重大进展?
    【由浅入深的VR技术之旅】初学VR要解决的三个核心技术问题
  • 原文地址:https://www.cnblogs.com/maxiaodoubao/p/4686566.html
Copyright © 2011-2022 走看看