文章来源:http://blog.csdn.net/shift_wwx/article/details/78854811
请转载的朋友标明出处,请支持原创~~
源码基于:Android 7.0
Android中定义了两种智能指针类型,一种是强指针sp(strong pointer),另外一种是弱指针(weak pointer)。其实称之为强引用和弱引用更合适一些。强指针与一般意义的智能指针概念相同,通过引用计数来记录有多少使用者在使用一个对象,如果所有使用者都放弃了对该对象的引用,则该对象将被自动销毁。
弱指针也指向一个对象,但是弱指针仅仅记录该对象的地址,不能通过弱指针来访问该对象,也就是说不能通过弱智真来调用对象的成员函数或访问对象的成员变量。要想访问弱指针所指向的对象,需首先通过wp类所提供的promote()方法将弱指针升级为强指针。弱指针所指向的对象是有可能在其它地方被销毁的,如果对象已经被销毁,wp的promote()方法将返回空指针,这样就能避免出现地址访问错的情况。
system/core/include/utils/StrongPointer.h
template<typename T>
class sp {
public:
inline sp() : m_ptr(0) { }
sp(T* other);
sp(const sp<T>& other);
sp(sp<T>&& other);
template<typename U> sp(U* other);
template<typename U> sp(const sp<U>& other);
template<typename U> sp(sp<U>&& other);
~sp();
// Assignment
sp& operator = (T* other);
sp& operator = (const sp<T>& other);
sp& operator = (sp<T>&& other);
template<typename U> sp& operator = (const sp<U>& other);
template<typename U> sp& operator = (sp<U>&& other);
template<typename U> sp& operator = (U* other);
//! Special optimization for use by ProcessState (and nobody else).
void force_set(T* other);
// Reset
void clear();
// Accessors
inline T& operator* () const { return *m_ptr; }
inline T* operator-> () const { return m_ptr; }
inline T* get() const { return m_ptr; }
// Operators
COMPARE(==)
COMPARE(!=)
COMPARE(>)
COMPARE(<)
COMPARE(<=)
COMPARE(>=)
private:
template<typename Y> friend class sp;
template<typename Y> friend class wp;
void set_pointer(T* ptr);
T* m_ptr;
};
从代码中我们可以得知:
对于模板,详细看 C++模板详解
template<typename T>
sp<T>::sp(T* other)
: m_ptr(other) {
if (other) //如果构造函数形参的指针不为null,该指针的计数加1,这个后面解释
other->incStrong(this);
}
template<typename T>
sp<T>::sp(const sp<T>& other)//实参为sp<T>类型的对象,这里形参为引用
: m_ptr(other.m_ptr) {
if (m_ptr)
m_ptr->incStrong(this);
}
template<typename T>
sp<T>::sp(sp<T>&& other) //这里C++11中的移动构造函数,会在另一篇博文中详解
: m_ptr(other.m_ptr) {
other.m_ptr = nullptr;
}
template<typename T> template<typename U>
sp<T>::sp(U* other) //这里大部分是子类往父类转换
: m_ptr(other) {
if (other)
((T*) other)->incStrong(this);
}
template<typename T> template<typename U>
sp<T>::sp(const sp<U>& other)
: m_ptr(other.m_ptr) {
if (m_ptr)
m_ptr->incStrong(this);
}
template<typename T> template<typename U>
sp<T>::sp(sp<U>&& other)//同样是C++11特性移动构造函数,后面详解
: m_ptr(other.m_ptr) {
other.m_ptr = nullptr;
}
sp构造就是为了给指针T或者指针U多一个引用的地方,所以,在构造的时候必须做两件事情:
构造的时候原来sp的引用为0,无需对m_ptr进行decStrong(),但下面的运算符重载就不是这样了。
对于incStrong 和 decStrong暂时理解为指针m_ptr的计数加1和减1,后面会详解。
template<typename T>
sp<T>& sp<T>::operator =(const sp<T>& other) {
T* otherPtr(other.m_ptr);
if (otherPtr)
otherPtr->incStrong(this);//参数other中的指针m_ptr要多一个引用了,调用incStrong()
if (m_ptr)
m_ptr->decStrong(this);//当前的指针需要被other代替,那么目前的指针m_ptr的引用计数需要减1
m_ptr = otherPtr;
return *this;
}
template<typename T>
sp<T>& sp<T>::operator =(sp<T>&& other) {
if (m_ptr)
m_ptr->decStrong(this);//这里是移动赋值,会将other中的m_ptr直接移动给这里的m_ptr,之前要先decStrong
m_ptr = other.m_ptr;
other.m_ptr = nullptr;
return *this;
}
template<typename T>
sp<T>& sp<T>::operator =(T* other) {
if (other)
other->incStrong(this);//直接指针赋值就更简单了
if (m_ptr)
m_ptr->decStrong(this);
m_ptr = other;
return *this;
}
template<typename T> template<typename U>
sp<T>& sp<T>::operator =(const sp<U>& other) {//考虑到子类向父类赋值
T* otherPtr(other.m_ptr);
if (otherPtr)
otherPtr->incStrong(this);
if (m_ptr)
m_ptr->decStrong(this);
m_ptr = otherPtr;
return *this;
}
template<typename T> template<typename U>
sp<T>& sp<T>::operator =(sp<U>&& other) {
if (m_ptr)
m_ptr->decStrong(this);
m_ptr = other.m_ptr;
other.m_ptr = nullptr;
return *this;
}
template<typename T> template<typename U>
sp<T>& sp<T>::operator =(U* other) {
if (other)
((T*) other)->incStrong(this);
if (m_ptr)
m_ptr->decStrong(this);
m_ptr = other;
return *this;
}
6个赋值函数,或者叫6个 “=” 的重载中注意的是原来的decStrong 和新的指针的incStrong。
template<typename T>
sp<T>::~sp() {
if (m_ptr)
m_ptr->decStrong(this);
}
当sp不在使用的时候,指针T *m_ptr需要将计数减1。
inline T& operator* () const { return *m_ptr; }
inline T* operator-> () const { return m_ptr; }
inline T* get() const { return m_ptr; }
例如:
class Test {
public:
Test() {}
~Test() {}
void test() { cout << "just for test ...\n";}
};
main () {
sp<Test> hehe(new Test()); //构造的时候可以直接传入指针
hehe->test(); //通过 -> 指向指针m_ptr,直接调用Test的test函数
*hehe.test(); //通过 * 找到对应的Test 引用
Test *t = hehe.get(); //sp 中get函数就是为了获取指针m_ptr
t->test();
}
template<typename T>
void sp<T>::force_set(T* other) {//特殊需要用,一般不会用到
other->forceIncStrong(this);
m_ptr = other;
}
template<typename T>
void sp<T>::clear() {//做sp rest功能使用,会将指针的计数减1,指针置为空指针,注意C++11上用nullptr
if (m_ptr) {
m_ptr->decStrong(this);
m_ptr = 0;
}
}
template<typename T>
void sp<T>::set_pointer(T* ptr) {//这个是private函数,wp在做promote的时候会使用到,wp通过friend方式调用到这里。
m_ptr = ptr;
}
带着这两个问题,看下一篇博文