下面是android 7.1.1中的源码
先从简单的LightRefBase开始, 它里面只用了简单的mCount来计数.
## LightRefBase
template
class LightRefBase
{
public:
inline LightRefBase() : mCount(0) { }
//计数+1
inline void incStrong(__attribute__((unused)) const void* id) const {
mCount.fetch_add(1, std::memory_order_relaxed);
}
inline void decStrong(__attribute__((unused)) const void* id) const {
//计数-1, 返回减1之前的值
if (mCount.fetch_sub(1, std::memory_order_release) == 1) {
std::atomic_thread_fence(std::memory_order_acquire);
delete static_cast(this); //如果减掉后引用计数为0, 删掉该引用
}
}
inline int32_t getStrongCount() const {
return mCount.load(std::memory_order_relaxed);
}
private:
mutable std::atomic mCount;
};
int main(int argc, char** argv)
{
//自定义LightClass 继承LightRefBase
LightClass* pLightClass = new LightClass();
//调用① sp的一个参数的构造函数
sp lpOut = pLightClass;
//pLightClass 引用计数+1, 所以下面输出 1
printf("Light Ref Count: %d.\n", pLightClass->getStrongCount());
{
//调用② sp的另一个构造函数
sp lpInner = lpOut;
//上面pLight的引用计数+1, 所以这里输出2
printf("Light Ref Count: %d.\n", pLightClass->getStrongCount());
}
//上面作用域结束所以, lpInner调用析构函数③
//pLightClass引用计数-1, 这里输出 1
printf("Light Ref Count: %d.\n", pLightClass->getStrongCount());
return 0;
}
//StrongPointer.h
//①
template
sp::sp(T* other) //other在上面的例子为pLightClass
: m_ptr(other) {
if (other)
//调用LightRefBase的incStrong, LightRefBase的mCount+1;
other->incStrong(this);
}
//②
template
sp::sp(const sp& other) //other参数在上面的例子中为lpOut
: m_ptr(other.m_ptr) { //other.m_ptr为 pLightClass, m_ptr其实就是pLightClass的引用
if (m_ptr)
m_ptr->incStrong(this); //引用计数+1
}
//③
template
sp::~sp() {
if (m_ptr) //m_ptr为pLightClass的引用
m_ptr->decStrong(this);
}
## RefBase
# RefBase原型
//RefBase.h
class RefBase
{
private:
//weakref_impl为RefBase的内部类weakref_type的实现类,
//mRefs包含强引用计数, 弱引用计数, flag, 以及指向外部类RefBase的指针mBase
weakref_impl* const mRefs;
protected:
RefBase(); //构造函数中 new weakref_impl()
virtual ~RefBase(); //析构做了较多工作
//! Flags for extendObjectLifetime()
enum { //没有了forever
OBJECT_LIFETIME_STRONG = 0x0000, //对象受强引用控制, 默认
OBJECT_LIFETIME_WEAK = 0x0001, //对象受弱引用控制
OBJECT_LIFETIME_MASK = 0x0001
};
public:
void incStrong(const void* id) const;
void decStrong(const void* id) const;
weakref_type* createWeak(const void* id) const;
//...省略
}
上面是RefBase中的几个重要函数声明, 接下来是weakref_impl的声明
# weakref_type, weakref_impl原型
//RefBase.h
class weakref_type
{
public:
void incWeak(const void* id);
void decWeak(const void* id);
bool attemptIncStrong(const void* id);
//..省略
}
//RefBase.cpp
class RefBase::weakref_impl : public RefBase::weakref_type //weakref_type定义了几个函数
{
public:
std::atomic mStrong; //强引用计数
std::atomic mWeak; //弱引用计数
RefBase* const mBase; //引用外部指针
std::atomic mFlags; //标记
//..省略空方法
}
后面都是控制weakref_impl对象, 这里只要记住有四个变量, 和加减引用计数的方法, 接下来先看下它们的实现
# weakref_type, weakref_impl实现
//RefBase.cpp
weakref_impl(RefBase* base)
: mStrong(INITIAL_STRONG_VALUE) //强引用计数默认值
, mWeak(0) //弱引用计数0
, mBase(base) //引用外部对象 RefBase
, mFlags(0){} //flag默认0, 表示受强引用控制
void RefBase::weakref_type::incWeak(const void* id)
{
weakref_impl* const impl = static_cast(this);
impl->addWeakRef(id); //空方法
const int32_t c __unused = impl->mWeak.fetch_add(1, //弱引用计数+1
std::memory_order_relaxed);
}
void RefBase::weakref_type::decWeak(const void* id)
{
weakref_impl* const impl = static_cast(this);
impl->removeWeakRef(id); //空方法
const int32_t c = impl->mWeak.fetch_sub(1, std::memory_order_release); //弱引用-1
if (c != 1) return; //减1后弱引用计数不为0, 直接返回
//弱引用计数为0, 接着往下执行
//弱引用计数>=强引用计数
atomic_thread_fence(std::memory_order_acquire);
int32_t flags = impl->mFlags.load(std::memory_order_relaxed);
if ((flags&OBJECT_LIFETIME_MASK) == OBJECT_LIFETIME_STRONG) {
// 受强引用计数影响, 默认
if (impl->mStrong.load(std::memory_order_relaxed)
== INITIAL_STRONG_VALUE) {
//如果强引用计数为初始值, 回收RefBase
delete impl->mBase;
} else {
//强引用计数为0, 回收weakref_impl
delete impl;
}
} else {
// 受弱引用计数控制, 回收RefBase
impl->mBase->onLastWeakRef(id);
delete impl->mBase;
}
}
bool RefBase::weakref_type::attemptIncStrong(const void* id)
{
//该方法是, 弱引用变为强引用, 所以强引用计数+1, 弱引用计数也需要+1
//这里弱引用计数先+1, 如果变为强引用失败, 则再-1
incWeak(id);
weakref_impl* const impl = static_cast(this);
int32_t curCount = impl->mStrong.load(std::memory_order_relaxed);
//下面判断成立, 说明已经有强引用, 说明可以, 升级为强引用
//while为了解决多线程的问题
while (curCount > 0 && curCount != INITIAL_STRONG_VALUE) {
if (impl->mStrong.compare_exchange_weak(curCount, curCount+1,
std::memory_order_relaxed)) {
break;
}
}
if (curCount <= 0 || curCount == INITIAL_STRONG_VALUE) {
// 两种情况
// - 没有过强引用
// - 或者强引用都被回收了
int32_t flags = impl->mFlags.load(std::memory_order_relaxed);
if ((flags&OBJECT_LIFETIME_MASK) == OBJECT_LIFETIME_STRONG) {
// 默认受强引用控制时
// 当最后的强引用被释放了, 所以curCount<=0
if (curCount <= 0) {
// 强引用<=0 肯定是从1减到了0, 根据decStrong()方法, 受强引用控制时, 释放RefBase
// 所以不能升级为强引用
decWeak(id); //弱引用计数-1, 因为上面加过1
return false;
}
//curCount为初始值, 说明没有过强引用, 可以尝试一下
while (curCount > 0) {
//mStrong + 1
if (impl->mStrong.compare_exchange_weak(curCount, curCount+1,
std::memory_order_relaxed)) {
break;
}
}
if (curCount <= 0) {
// 其他线程破坏了这次的升级, promote()失败
decWeak(id);
return false;
}
} else {
// 受弱引用控制
// onIncStrongAttempted()默认为true, 但是可以重写该方法
// 能否promote()成功取决于开发者.
if (!impl->mBase->onIncStrongAttempted(FIRST_INC_STRONG, id)) {
decWeak(id);
return false;
}
// 可以升级为强引用, 强引用计数+1
curCount = impl->mStrong.fetch_add(1, std::memory_order_relaxed);
// 多线程问题, 别的线程动了强引用计数
if (curCount != 0 && curCount != INITIAL_STRONG_VALUE) {
impl->mBase->onLastStrongRef(id);
}
}
}
impl->addStrongRef(id);// 空方法
// 修正强引用计数为1
if (curCount == INITIAL_STRONG_VALUE) {
impl->mStrong.fetch_sub(INITIAL_STRONG_VALUE,
std::memory_order_relaxed);
}
return true;
}
# RefBase实现
//RefBase.cpp
RefBase::RefBase() //无参构造函数
: mRefs(new weakref_impl(this)){}
RefBase::~RefBase() //析构函数
{
if (mRefs->mStrong.load(std::memory_order_relaxed)
== INITIAL_STRONG_VALUE) {
//没有用过强引用, 删除weakref_impl
delete mRefs;
} else {
int32_t flags = mRefs->mFlags.load(std::memory_order_relaxed);
if ((flags & OBJECT_LIFETIME_MASK) != OBJECT_LIFETIME_STRONG) {
if (mRefs->mWeak.load(std::memory_order_relaxed) == 0) {
//受弱引用控制, 并且若引用计数 = 0, 删除weakref_impl
delete mRefs;
}
}
}
// for debugging purposes, clear this.
const_cast(mRefs) = NULL;
}
//wp中需要调用
RefBase::weakref_type* RefBase::createWeak(const void* id) const
{
mRefs->incWeak(id);
return mRefs;
}
//incStrong
void RefBase::incStrong(const void* id) const
{
weakref_impl* const refs = mRefs;
refs->incWeak(id); //弱引用计数+1
refs->addStrongRef(id); //空方法
//强引用+1
const int32_t c = refs->mStrong.fetch_add(1, std::memory_order_relaxed);
if (c != INITIAL_STRONG_VALUE) {
return;
}
//强引用默认值为1<<28, 减去1<<28, 现在值为1
int32_t old = refs->mStrong.fetch_sub(INITIAL_STRONG_VALUE,
std::memory_order_relaxed);
refs->mBase->onFirstRef();
}
void RefBase::decStrong(const void* id) const
{
weakref_impl* const refs = mRefs;
refs->removeStrongRef(id);//空方法
//强引用-1
const int32_t c = refs->mStrong.fetch_sub(1, std::memory_order_release);
if (c == 1) { //减去后强引用计数 = 0
std::atomic_thread_fence(std::memory_order_acquire);
refs->mBase->onLastStrongRef(id);//可继承
int32_t flags = refs->mFlags.load(std::memory_order_relaxed);
if ((flags&OBJECT_LIFETIME_MASK) == OBJECT_LIFETIME_STRONG) {
//受强引用计数控制, 默认, 删掉RefBase, 并且调用RefBase的析构函数
delete this;
}
}
refs->decWeak(id);
}
-
RefBase::RefBase()
new weakref_impl(), weakref_impl初始化
-
RefBase::~RefBase()
强引用计数为初始值 || (受弱引用控制&&弱引用计数==0) -> 删掉weakref_impl
-
RefBase::incStrong()
调用 weakref_type::incWeak (弱引用+1)
强引用+1(如果第一次加1, 那么减掉初始值, 最终为1),
-
RefBase::decStrong()
强引用-1, 减去后如果强引用计数为0, 并且受强引用控制, 释放RefBase(实际对象)
调用 weakref_type::decWeak (弱引用-1, 还有其他逻辑)
-
RefBase::weakref_type::incWeak()
强引用+1
-
RefBase::weakref_type::decWeak()
弱引用-1, 减去后如果弱引用计数为0, 分两种情况, 受强引用控制, 受弱引用控制
其实弱引用计数为0, 不管受强引用还是弱引用控制, RefBase和weakref_impl都需要释放, 下面的判断是为了不重复释放
-
受强引用控制, 强引用计数为初始值, 释放RefBase, 不为初始值, 释放weakref_impl
强引用计数为初始值, 释放RefBase, RefBase调用析构函数, 释放weakref_impl
强引用计数不为初始值说明, 调用过decStrong(), 并且受强引用控制, 所以会释放RefBase, 这里只需再释放weakref_impl就可以了
-
受弱引用控制, 释放RefBase
受弱引用控制, 释放RefBase, RefBase调用析构函数, 释放weakref_impl
-
-
RefBase::weakref_type::attemptIncStrong()
不考虑多线程的情况下, 首先如果已经有强引用, 那么可以直接升级强引用.
当强引用<=0, 或者没有初始化过强引用时分两种情况, 受强引用或者弱引用控制
-
受强引用控制
强引用<=0, 说明RefBase已经被释放了, 升级失败
强引用为默认值, 说明没有过强引用, 可以升级
-
受弱引用控制
首先判断开发者是否希望可以升级, 默认为true, 升级OK
-
RefBase的重要函数都说明完了, 接下来是strong pointer和 weak pointer, 如果上面的RefBase弄明白了, sp和wp就很简单, 只要关注它们的构造函数和析构函数, 加上wp的promote()函数即可.
## sp和wp
# sp实现
//StrongPointer.h
template
class sp {
public:
inline sp() : m_ptr(0) { }
//构造方法很多, 其他也都一样调用RefBase的incStrong()函数
template
sp::sp(const sp& other)
: m_ptr(other.m_ptr) {
if (m_ptr)
m_ptr->incStrong(this);
}
//析构函数
template
sp::~sp() {
if (m_ptr)
m_ptr->decStrong(this);
}
// 特殊! 用于ProcessState, 不关注
void force_set(T* other);
// 操作符重载 sp可以自由使用引用对象
inline T& operator* () const { return *m_ptr; }
inline T* operator-> () const { return m_ptr; }
inline T* get() const { return m_ptr; }
// 也是为了 sp自由使用引用对象, 宏定义就不贴了
COMPARE(==)
COMPARE(!=)
COMPARE(>)
COMPARE(<)
COMPARE(<=)
COMPARE(>=)
private:
template friend class sp;
template friend class wp;
void set_pointer(T* ptr) { m_ptr = ptr; }
T* m_ptr; //引用对象
};
这里只需明白3点:
- 构造函数调用 incStrong(), 强引用+1, 弱引用+1
- 析构函数调用 decStrong(), 强引用-1, 弱引用-1 (还有其他一些逻辑)
- sp可以自由操作引用对象
# wp实现
//RefBase.h
template
class wp
{
public:
template //构造函数
wp::wp(T* other): m_ptr(other)
{
//createWeak()方法很简单, 上面有实现, 只是调用下incWeak, 返回weakref_impl对象
if (other) m_refs = other->createWeak(this);
}
template //析构函数
wp::~wp()
{
if (m_ptr) m_refs->decWeak(this);
}
template
sp wp::promote() const //重点方法, wp升级sp
{
sp result;
if (m_ptr && m_refs->attemptIncStrong(&result)) {
result.set_pointer(m_ptr);
}
return result; //如果升级失败, 引用对象为空
}
private:
template friend class sp;
template friend class wp;
T* m_ptr; //引用对象
weakref_type* m_refs; //RefBase中的weakref_impl, 因为要调用weakref_impl的方法
};
wp的要明白4点:
- 构造函数调用 createWeak(), 弱引用+1
- 析构函数调用 decWeak() 弱引用-1 (还有其他一些逻辑)
- wp不可以自由操作引用对象
- wp的promote()方法, 可以升级为sp, 但是如果升级失败sp的引用对象为空, 所以需要做判断
OK, 智能指针的基本方法都已经讲清楚, 这里用老罗的例子实践一下.
class WeightClass : public RefBase
{
public:
void printRefCount()
{
int32_t strong = getStrongCount();
weakref_type* ref = getWeakRefs();
printf("-----------------------\n");
printf("Strong Ref Count: %d.\n", strong); //打印强引用计数
printf("Weak Ref Count: %d.\n", ref->getWeakCount()); //打印弱引用计数
printf("-----------------------\n");
}
};
class StrongClass : public WeightClass
{
public:
StrongClass()
{
printf("Construct StrongClass Object.\n");
}
virtual ~StrongClass()
{
printf("Destory StrongClass Object.\n");
}
};
class WeakClass : public WeightClass
{
public:
WeakClass()
{
extendObjectLifetime(OBJECT_LIFETIME_WEAK); //受弱引用控制
printf("Construct WeakClass Object.\n");
}
virtual ~WeakClass()
{
printf("Destory WeakClass Object.\n");
}
};
void TestStrongClass(StrongClass* pStrongClass)
{
wp wpOut = pStrongClass; //弱引用计数 +1
pStrongClass->printRefCount();
{
sp spInner = pStrongClass; //强引用计数+1, 弱引用计数+1
pStrongClass->printRefCount();
}//调用sp的析构函数, 强引用 = 0, 弱引用 = 1, 因受强引用控制, 所以对象被删除
sp spOut = wpOut.promote(); //升级失败
printf("spOut: %p.\n", spOut.get());
}
void TestWeakClass(WeakClass* pWeakClass)
{
wp wpOut = pWeakClass; //弱引用计数 +1
pWeakClass->printRefCount();
{
sp spInner = pWeakClass; //强引用计数+1, 弱引用计数+1
pWeakClass->printRefCount();
}//调用sp的析构函数, 强引用 = 0, 弱引用 = 1, 因受弱引用控制, 所以对象不会被删除
pWeakClass->printRefCount();
sp spOut = wpOut.promote(); //升级成功
printf("spOut: %p.\n", spOut.get());
}
int main(int argc, const char * argv[]) {
printf("Test Strong Class: \n");
StrongClass* pStrongClass = new StrongClass();
TestStrongClass(pStrongClass);
printf("\nTest Weak Class: \n");
WeakClass* pWeakClass = new WeakClass();
TestWeakClass(pWeakClass);
return 0;
}
//输出:
/*
Test Strong Class:
Construct StrongClass Object.
-----------------------
Strong Ref Count: 268435456.
Weak Ref Count: 1.
-----------------------
-----------------------
Strong Ref Count: 1.
Weak Ref Count: 2.
-----------------------
Destory StrongClass Object.
spOut: 0x0.
Test Weak Class:
Construct WeakClass Object.
-----------------------
Strong Ref Count: 268435456.
Weak Ref Count: 1.
-----------------------
-----------------------
Strong Ref Count: 1.
Weak Ref Count: 2.
-----------------------
-----------------------
Strong Ref Count: 0.
Weak Ref Count: 1.
-----------------------
spOut: 0x100300060.
Destory WeakClass Object.
*/