智能指针(一)
sp 和 wp 简析
在 Android 系统中,sp 和 wp 称为智能指针(android refbase 类(sp 和 wp))。其实 sp 和 wp 就是 Android 为其 C++实现的自动垃圾回收机制。如果具体到内部实现,sp 和 wp 实际上只是一个实现垃圾回收功能的接口而已,比如说对*,->的重载,是为了使其看起来跟真正的指针一样,而真正实现垃圾回收的是 refbase 这个基类。这部分代码位于如下文件中。
/frameworks/base/include/utils/RefBase.h
在此所有的类都会虚继承于 refbase 类,因为它实现了达到 Android 垃圾回收所需要的所有function,因此所有的对象声明出来以后都具备了自动释放自己的能力,也就是说实际上智能指针就是对象本身,它会维持一个对本身强引用和弱引用的计数,一旦强引用计数为 0 它就会释放掉自己。
(1)sp
Sp 并不是 smart pointer 的缩写,而是 strong pointer 的缩写,它的内部包含了一个指向对象的指针。简单分析 sp 的一个构造函数,内容如下。
template< typename T>
sp< T>::sp(T* other)
: m_ptr(other)
{
if (other) other->incStrong(this);
}
比如,声明一个对象,内容如下。
sp< CameraHardwareInterface> hardware(new CameraHal());
实际上 sp 指针对本身并没有进行操作,就是一个指针的赋值,包含了一个指向对象的指针,但是对象会对本身增加一个强引用计数,这个 incStrong 的实现就在 refbase 类里面。新建出来一个CameraHal 对象,赋值给 sp< CameraHardwareInterface>时,它的强引用计数就会从 0 变为 1。因此每次将对象赋值给一个 sp 指针时,对象的强引用计数都会加 1,下面再分析 sp 的析构函数。
template< typename T>
sp< T>::~sp()
{
if (m_ptr) m_ptr->decStrong(this);
}
实际上每删除一个 sp 对象时,sp 指针指向的对象的强引用计数就会减 1,当对象的强引用计数
为 0 时,这个对象就会被自动释放掉。
(2)wp
wp 就是 Weak Pointer 的缩写,弱引用指针的原理就是为了应用 Android 垃圾回收来减少对那些“胖子”对象对内存的占用,首先来分析 wp 的一个构造函数。
wp< T>::wp(T* other)
: m_ptr(other)
{
if (other) m_refs = other->createWeak(this);
}
它和 sp 一样,仅仅对指针进行了赋值而已,对象本身会增加一个对自身的弱引用计数,同时
wp 还包含一个 m_ref 指针,这个指针主要在将 wp 升级为 sp 时使用。
template< typename T>
sp< T> wp< T>::promote() const
{
return sp< T>(m_ptr, m_refs);
}
template< typename T>
sp< T>::sp(T* p, weakref_type* refs)
: m_ptr((p && refs->attemptIncStrong(this)) ? p : 0)
{
}
在此对 wp 指针唯一能做的就是将 wp 指针升级为一个 sp 指针,然后判断是否升级成功,如果
成功说明对象依旧存在,如果失败说明对象已经被释放掉了。
wp 指针在单例中应用很多,确保mhardware 对象只有一个,比如:
wp< CameraHardwareInterface> CameraHardwareStub::singleton;
sp< CameraHardwareInterface> CameraHal::createInstance()
{
LOG_FUNCTION_NAME
if (singleton != 0) {
sp< CameraHardwareInterface> hardware = singleton.promote();
if (hardware != 0) {
return hardware;
}
}
sp< CameraHardwareInterface> hardware(new CameraHal()); //强引用加 1
singleton = hardware;//弱引用加 1
return hardware;//赋值构造函数,强引用加 1
}
//hardware 被删除,强引用减 1