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
原文地址:https://www.cnblogs.com/maxiaodoubao/p/4686566.html