Android中的强指针和弱指针

C++中,我们常用指针去使用某个对象实例,但随着代码对该对象使用的增加,比如越来越多的其它的类或模块需要使用该对象,那么什么时候安全地释放该对象就是个问题。比如,某处使用完该对象后,认为不再使用,便释放了它,但另外的某些类或模块还需使用,这时,就会引起内存的非法使用问题,在Linux下是signal 11错误,也就是段错误(Segmentation Fault)。为了解决这种问题,引入了智能指针,当使用该对象时,令其引用计数加1,释放时只是减去1。当减为0时,就自动释放指针所指对象。C++中,通常使用模板实现这一机制。但是当两个智能指针相互引用对方时,即使其它地方都释放它们,它们的引用计数也会为1,最终导致内存泄漏。这就引入了弱指针的概念。

Android中的随处可见的sp<XXX>wp<XXX>。这里的XXX是对象的类,spwp是模版,分别实现了强指针(Strong Pointer)和弱指针(Weak Pointer)。模板具体化后的一个实例XXX,具有指针的属性,可以简单地把它理解一个指针,只不过比普通的指针特殊一点而已。弱指针不能直接被当作指针来使用,当需要当作指针来使用时,需要使用其成员函数promote来“提升”为强指针。弱指针指向的对象可能已经被销毁,这时,若使用promote得到的指针为空指针。

 

引用计数功能的实现

RefBase是引用计数的基类(见文件RefBase.h),在它里面还定义了一个嵌套类weakref_type,在其实现文件RefBase.cpp里还定义了一个类weakref_impl ,它继承自嵌套类weakref_type,而RefBase中包含一个私有数据成员:指向weakref_impl 的指针。可以看出,RefBase中的数据实体就是weakref_impl,后者继承自其嵌套类weakref_type。其示意图如下:

 

 

 

 

 

这样,相当于将一部分成员函数(weakref_type的成员函数)和数据成员(weakref_impl的数据成员)封装起来,作为私有的一个逻辑实体,只被Refbase内部的实现使用,而RefBase的公有成员才是外界使用的APIRefBase通过指针mRefs使用内部的引用计数数据。而内部引用计数实体对象也可以通过 mBase这个成员来使用其“容器”对象RefBase.

weakref_impl里面的数据成员信息如下:

volatile int32_t mStrong;//强引用计数
volatile int32_t mWeak;//
弱引用计数
RefBase* const mBase; //
指向其“容器”类RefBase
volatile int32_t mFlags;//
对象销毁策略标志:若为0,则强引用计数为0时即销毁对象;若为1OBJECT_LIFETIME_WEAK=0×0001),则强弱引用计数均为0时销毁;若为3(OBJECT_LIFETIME_FOREVER = 0×0003),则由创建者管理,即不依赖RefBase引用计数。

 

强指针和弱指针都是模板类:

template <typename T>

class sp{

//……此处省略了部分代码

inline T& operator* () const { return *m_ptr; }
inline T* operator-> () const { return m_ptr; }
inline T* get() const { return m_ptr; }

//……此处省略了部分代码

T* m_ptr;//实际指向对象的指针

};

template <typename T>

class wp{

//……此处省略了部分代码

sp<T>promote() const;

//……此处省略了部分代码

T* m_ptr;
weakref_type* m_refs;

};

强指针因为重载了两个操作符*->,因此具有形式上跟普通指针一样的用法,而弱指则没有重载这两个操作符,只能先被“提升”为强指针后,才可以当作普通指针来使用。

如果需要使用智能指针将对象保护起来,只要让其继承RefBase,并将析构函数声明为virtual的,就可以使用智能指针。

 

可以参考链接来获取详细介绍:

 

参考: Android系统的智能指针(轻量级指针、强指针和弱指针)的实现原理分析
http://blog.csdn.net/luoshengyang/article/details/6786239 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值