前言:
上一篇关于sp的博文,通过source code 来解释了sp的功能,sp被称为强指针,但是强引用更贴切点。那么弱引用wp到底有什么功能?与sp有什么区别?这一篇通过source code来解释。
本文总结基于Android 7.0
source code:system/core/include/utils/RefBase.h template
class wp
{
public:
typedef typename RefBase::weakref_type weakref_type;
inline wp() : m_ptr(0){ }
wp(T* other);
wp(const wp& other);
wp(const sp& other);
template wp(U* other);
template wp(const sp& other);
template wp(const wp& other);
~wp();
// Assignment
wp& operator = (T* other);
wp& operator = (const wp& other);
wp& operator = (const sp& other);
template wp& operator = (U* other);
template wp& operator = (const wp& other);
template wp& operator = (const sp& other);
void set_object_and_refs(T* other, weakref_type* refs);
// promotion to sp
sp 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& o) const {
return (m_ptr == o.m_ptr) && (m_refs == o.m_refs);
}
template
inline bool operator == (const wp& o) const {
return m_ptr == o.m_ptr;
}
inline bool operator > (const wp& o) const {
return (m_ptr == o.m_ptr) ? (m_refs > o.m_refs) : (m_ptr > o.m_ptr);
}
template
inline bool operator > (const wp& o) const {
return (m_ptr == o.m_ptr) ? (m_refs > o.m_refs) : (m_ptr > o.m_ptr);
}
inline bool operator < (const wp& o) const {
return (m_ptr == o.m_ptr) ? (m_refs < o.m_refs) : (m_ptr < o.m_ptr);
}
template
inline bool operator < (const wp& o) const {
return (m_ptr == o.m_ptr) ? (m_refs < o.m_refs) : (m_ptr < o.m_ptr);
}
inline bool operator != (const wp& o) const { return m_refs != o.m_refs; }
template inline bool operator != (const wp& o) const { return !operator == (o); }
inline bool operator <= (const wp& o) const { return !operator > (o); }
template inline bool operator <= (const wp& o) const { return !operator > (o); }
inline bool operator >= (const wp& o) const { return !operator < (o); }
template inline bool operator >= (const wp& o) const { return !operator < (o); }
private:
template friend class sp;
template 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
wp::wp(T* other)
: m_ptr(other)
{
if (other) m_refs = other->createWeak(this);
}
template
wp::wp(const wp& other)
: m_ptr(other.m_ptr), m_refs(other.m_refs)
{
if (m_ptr) m_refs->incWeak(this);
}
template
wp::wp(const sp& other)
: m_ptr(other.m_ptr)
{
if (m_ptr) {
m_refs = m_ptr->createWeak(this);
}
}
template template
wp::wp(U* other)
: m_ptr(other)
{
if (other) m_refs = other->createWeak(this);
}
template template
wp::wp(const wp& other)
: m_ptr(other.m_ptr)
{
if (m_ptr) {
m_refs = other.m_refs;
m_refs->incWeak(this);
}
}
template template
wp::wp(const sp& other)
: m_ptr(other.m_ptr)
{
if (m_ptr) {
m_refs = m_ptr->createWeak(this);
}
}
template
wp::~wp()
{
if (m_ptr) m_refs->decWeak(this);
}
从构造函数可以看出来几点与sp不同的地方:
1、并不是像 sp那样通过incStrong 和decStrong方式控制计数,而是通过createWeak 、incWeak、decWeak来控制,具体这几个函数是做什么的?与sp的两种函数有什么区别?后面解释。
2、并没有像 sp那样有移动构造函数,为什么呢?
再来看下赋值运算符的重载: template
wp& wp::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
wp& wp::operator = (const wp& 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
wp& wp::operator = (const sp& 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 template
wp& wp::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 template
wp& wp::operator = (const wp& 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 template
wp& wp::operator = (const sp& 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
sp wp::promote() const
{
sp 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就全然明白。