Android 智能指针详解 -- wp

来源:互联网 发布:jaba 并发编程 编辑:程序博客网 时间:2024/05/18 06:30

来源:

http://blog.csdn.net/shift_wwx/article/details/78860866


前言:

上一篇关于sp的博文,通过source code 来解释了sp的功能,sp被称为强指针,但是强引用更贴切点。那么弱引用wp到底有什么功能?与sp有什么区别?这一篇通过source code来解释。


本文总结基于Android 7.0


source code:system/core/include/utils/RefBase.h

template <typename T>class wp{public:    typedef typename RefBase::weakref_type weakref_type;        inline wp() : m_ptr(0) { }    wp(T* other);    wp(const wp<T>& other);    wp(const sp<T>& other);    template<typename U> wp(U* other);    template<typename U> wp(const sp<U>& other);    template<typename U> wp(const wp<U>& other);    ~wp();        // Assignment    wp& operator = (T* other);    wp& operator = (const wp<T>& other);    wp& operator = (const sp<T>& other);        template<typename U> wp& operator = (U* other);    template<typename U> wp& operator = (const wp<U>& other);    template<typename U> wp& operator = (const sp<U>& other);        void set_object_and_refs(T* other, weakref_type* refs);    // promotion to sp        sp<T> promote() const;    // Reset        void clear();    // Accessors        inline  weakref_type* get_refs() const { return m_refs; }        inline  T* unsafe_get() const { return m_ptr; }    // Operators    COMPARE_WEAK(==)    COMPARE_WEAK(!=)    COMPARE_WEAK(>)    COMPARE_WEAK(<)    COMPARE_WEAK(<=)    COMPARE_WEAK(>=)    inline bool operator == (const wp<T>& o) const {        return (m_ptr == o.m_ptr) && (m_refs == o.m_refs);    }    template<typename U>    inline bool operator == (const wp<U>& o) const {        return m_ptr == o.m_ptr;    }    inline bool operator > (const wp<T>& o) const {        return (m_ptr == o.m_ptr) ? (m_refs > o.m_refs) : (m_ptr > o.m_ptr);    }    template<typename U>    inline bool operator > (const wp<U>& o) const {        return (m_ptr == o.m_ptr) ? (m_refs > o.m_refs) : (m_ptr > o.m_ptr);    }    inline bool operator < (const wp<T>& o) const {        return (m_ptr == o.m_ptr) ? (m_refs < o.m_refs) : (m_ptr < o.m_ptr);    }    template<typename U>    inline bool operator < (const wp<U>& o) const {        return (m_ptr == o.m_ptr) ? (m_refs < o.m_refs) : (m_ptr < o.m_ptr);    }                         inline bool operator != (const wp<T>& o) const { return m_refs != o.m_refs; }    template<typename U> inline bool operator != (const wp<U>& o) const { return !operator == (o); }                         inline bool operator <= (const wp<T>& o) const { return !operator > (o); }    template<typename U> inline bool operator <= (const wp<U>& o) const { return !operator > (o); }                         inline bool operator >= (const wp<T>& o) const { return !operator < (o); }    template<typename U> inline bool operator >= (const wp<U>& o) const { return !operator < (o); }private:    template<typename Y> friend class sp;    template<typename Y> friend class wp;    T*              m_ptr;    weakref_type*   m_refs;};
通过定义与sp比较:

1、都是模板类

2、都有7个构造函数和6个赋值重载函数
3、因为多了成员变量m_refs,所以,比较的运算符进行了重载,sp中没有m_refs,所以直接用宏COMPARE_WEAK

4、都有指针T* m_ptr

5、wp多了一个promote函数,为了向sp转换

6、wp并没有sp中重载运算符 * 和运算符 ->


再来看下构造函数和析构函数的实现:

template<typename T>wp<T>::wp(T* other)    : m_ptr(other){    if (other) m_refs = other->createWeak(this);}template<typename T>wp<T>::wp(const wp<T>& other)    : m_ptr(other.m_ptr), m_refs(other.m_refs){    if (m_ptr) m_refs->incWeak(this);}template<typename T>wp<T>::wp(const sp<T>& other)    : m_ptr(other.m_ptr){    if (m_ptr) {        m_refs = m_ptr->createWeak(this);    }}template<typename T> template<typename U>wp<T>::wp(U* other)    : m_ptr(other){    if (other) m_refs = other->createWeak(this);}template<typename T> template<typename U>wp<T>::wp(const wp<U>& other)    : m_ptr(other.m_ptr){    if (m_ptr) {        m_refs = other.m_refs;        m_refs->incWeak(this);    }}template<typename T> template<typename U>wp<T>::wp(const sp<U>& other)    : m_ptr(other.m_ptr){    if (m_ptr) {        m_refs = m_ptr->createWeak(this);    }}template<typename T>wp<T>::~wp(){    if (m_ptr) m_refs->decWeak(this);}
从构造函数可以看出来几点与sp不同的地方:

1、并不是像 sp那样通过incStrong 和decStrong方式控制计数,而是通过createWeak 、incWeak、decWeak来控制,具体这几个函数是做什么的?与sp的两种函数有什么区别?后面解释。

2、并没有像 sp那样有移动构造函数,为什么呢?

再来看下赋值运算符的重载:

template<typename T>wp<T>& wp<T>::operator = (T* other){    weakref_type* newRefs =        other ? other->createWeak(this) : 0;//wp 中指针other通过createWeak创建m_refs    if (m_ptr) m_refs->decWeak(this); //原来的m_refs需要decWeak    m_ptr = other;    m_refs = newRefs;    return *this;}template<typename T>wp<T>& wp<T>::operator = (const wp<T>& other){    weakref_type* otherRefs(other.m_refs);    T* otherPtr(other.m_ptr);    if (otherPtr) otherRefs->incWeak(this);    if (m_ptr) m_refs->decWeak(this);    m_ptr = otherPtr;    m_refs = otherRefs;    return *this;}template<typename T>wp<T>& wp<T>::operator = (const sp<T>& other){    weakref_type* newRefs =        other != NULL ? other->createWeak(this) : 0;//同形参为T* other,需要createWeak    T* otherPtr(other.m_ptr);    if (m_ptr) m_refs->decWeak(this);    m_ptr = otherPtr;    m_refs = newRefs;    return *this;}template<typename T> template<typename U>wp<T>& wp<T>::operator = (U* other){    weakref_type* newRefs =        other ? other->createWeak(this) : 0;    if (m_ptr) m_refs->decWeak(this);    m_ptr = other;    m_refs = newRefs;    return *this;}template<typename T> template<typename U>wp<T>& wp<T>::operator = (const wp<U>& other){    weakref_type* otherRefs(other.m_refs);    U* otherPtr(other.m_ptr);    if (otherPtr) otherRefs->incWeak(this);    if (m_ptr) m_refs->decWeak(this);    m_ptr = otherPtr;    m_refs = otherRefs;    return *this;}template<typename T> template<typename U>wp<T>& wp<T>::operator = (const sp<U>& other){    weakref_type* newRefs =        other != NULL ? other->createWeak(this) : 0;    U* otherPtr(other.m_ptr);    if (m_ptr) m_refs->decWeak(this);    m_ptr = otherPtr;    m_refs = newRefs;    return *this;}
通过赋值运算符重载看到,一般的指针在使用wp时,需要createWeak,如果已经是wp引用,直接incWeak

最后来看下promote:

template<typename T>sp<T> wp<T>::promote() const{    sp<T> result;    if (m_ptr && m_refs->attemptIncStrong(&result)) {        result.set_pointer(m_ptr);    }    return result;}

遗留问题:

1、wp 中m_refs 到底是什么意思?

2、构造或者是赋值的时候,为什么指针用的是createWeak,而m_refs 用的是incWeak 和decWeak,又有什么作用?

3、wp称为弱指针也可以,确切的看并没有看到指针使用的地方,那wp如何使用?

4、sp的博文中遗留的问题decStrong 和incStrong的具体实现是什么?为什么控制指针的计数?


这些问题需要看下RefBase 就全然明白。