C++ 智能指针(二)

2014-11-24 08:15:58 · 作者: · 浏览: 2
t impl = static_cast (this); impl->mWeak++; } void RefBase::weakref_type::decWeak(const void* id) { weakref_impl* const impl = static_cast (this); const int c = --impl->mWeak; if (c != 0) return; if ((impl->mFlags&OBJECT_LIFETIME_WEAK) != OBJECT_LIFETIME_WEAK) { if (impl->mStrong == INITIAL_STRONG_VALUE){ delete impl->mBase; } else { delete impl; } } else { if ((impl->mFlags&OBJECT_LIFETIME_FOREVER) != OBJECT_LIFETIME_FOREVER) { delete impl->mBase; } } } bool RefBase::weakref_type::attemptIncStrong(const void* id) { incWeak(id); weakref_impl* const impl = static_cast (this); int curCount = impl->mStrong; if (curCount > 0 && curCount != INITIAL_STRONG_VALUE) { impl->mStrong = curCount + 1; curCount = impl->mStrong; } if (curCount <= 0 || curCount == INITIAL_STRONG_VALUE) { bool allow; if (curCount == INITIAL_STRONG_VALUE) { allow = (impl->mFlags&OBJECT_LIFETIME_WEAK) != OBJECT_LIFETIME_WEAK || impl->mBase->onIncStrongAttempted(FIRST_INC_STRONG, id); } else { allow = (impl->mFlags&OBJECT_LIFETIME_WEAK) == OBJECT_LIFETIME_WEAK && impl->mBase->onIncStrongAttempted(FIRST_INC_STRONG, id); } if (!allow) { decWeak(id); return false; } curCount = impl->mStrong++; } if (curCount == INITIAL_STRONG_VALUE) { impl->mStrong = impl->mStrong - INITIAL_STRONG_VALUE; } return true; } int RefBase::weakref_type::getWeakCount() const { return static_cast (this)->mWeak; } RefBase::weakref_type* RefBase::createWeak(const void* id) const { mRefs->incWeak(id); return mRefs; } RefBase::weakref_type* RefBase::getWeakRefs() const { return mRefs; } RefBase::RefBase() : mRefs(new weakref_impl(this)) { } RefBase::~RefBase() { if (mRefs->mWeak == 0) { delete mRefs; } } void RefBase::extendObjectLifetime(int mode) { mRefs->mFlags = mode; } bool RefBase::onIncStrongAttempted(int flags, const void* id) { return (flags&FIRST_INC_STRONG) true : false; }

void RefBase::decStrong(const void* id) const
{
    weakref_impl* const refs = mRefs;
    const int c = --refs->mStrong;
    if (c == 0) {
        if ((refs->mFlags&OBJECT_LIFETIME_WEAK) != OBJECT_LIFETIME_WEAK) {
            delete this;
        }
    }

    refs->decWeak(id);
}
减少强指针时候,同时减少弱指针,如果强指针为0,并且受强指针控制,那么调用子类和RefBase的析构函数

void RefBase::weakref_type::decWeak(const void* id)
{
    weakref_impl* const impl = static_cast
  
   (this);
    const int c = --impl->mWeak;

    if (c != 0) return;

    if ((impl->mFlags&OBJECT_LIFETIME_WEAK) != OBJECT_LIFETIME_WEAK) {
        if (impl->mStrong == INITIAL_STRONG_VALUE){
            delete impl->mBase;
        }
        else {
            delete impl;
        }
    } else {
        if ((impl->mFlags&OBJECT_LIFETIME_FOREVER) != OBJECT_LIFETIME_FOREVER) {
            delete impl->mBase;
        }
    }
}
  

RefBase::~RefBase()
{
    if (mRefs->mWeak == 0) {
        delete mRefs;
    }
}

减少弱指针,如果弱指针为0,并且受弱指针控制,那么调用delete impl->mBase,调用上面的析构函数,因为此时mWeek==0,所以执行delete mRefs

如果弱指针为0,并且不受强指针,也不受弱指针控制,那么由自己调用delete来删除

如果弱指针为0,并且受强指针控制,如果强指针为0,那么只delete impl,因为RefBase及其子类已经被delelte掉了

如果弱指针为0,并且受强指针控制,如果强指针为INITIAL_STRONG_VALUE,那么说明RefBase及其子类还没有删除,那么要delelte impl->mBase,调用上面的析构函数,因为此时mWeek==0,所以执行delete mRefs

bool RefBase::weakref_type::attemptIncStrong(const void* id)
{
    incWeak(id);


    weakref_impl* const impl = static_cast
  
   (this);


    int curCount = impl->mStrong;
    if (curCount > 0 && curCount != INITIAL_STRONG_VALUE) {
	    impl->mStrong = curCount + 1;
        curCount = impl->mStrong;
    }


    if (curCount <= 0 || curCount == INITIAL_STRONG_VALUE) {
        bool allow;
        if (curCount == INITIAL_STRONG_VALUE) {
            allow = (impl->mFlags&OBJECT_LIFETIME_WEAK) != OBJECT_LIFETIME_WEAK
                  || impl->mBase->onIncStrongAttempted(FIRST_INC_STRONG, id);
        } else {
            allow = (impl->mF