C++ 智能指针
来源:互联网 发布:澳洲上市公司数据查询 编辑:程序博客网 时间:2024/06/11 04:08
本文参考http://blog.csdn.net/luoshengyang/article/details/6786239
一、RefBash.h
class RefBase{public: void incStrong(const void* id) const; void decStrong(const void* id) const; int getStrongCount() const; class weakref_type { public:RefBase* refBase() const;void incWeak(const void* id);void decWeak(const void* id);bool attemptIncStrong(const void* id);int getWeakCount() const; }; weakref_type* createWeak(const void* id) const; weakref_type* getWeakRefs() const;protected: RefBase(); virtual ~RefBase();//delete this时候会调用子类 enum {OBJECT_LIFETIME_WEAK = 0x0001,OBJECT_LIFETIME_FOREVER = 0x0003 }; void extendObjectLifetime(int mode); enum {FIRST_INC_STRONG = 0x0001 }; virtual bool onIncStrongAttempted(int flags, const void* id);//子类可以覆盖private: //friend class weakref_type; class weakref_impl; //不能include,只能前向声明 RefBase(const RefBase& o); RefBase& operator=(const RefBase& o); weakref_impl* const mRefs;};// ---------------------------------------------------------------------------template <typename T>class sp{public:typedef typename RefBase::weakref_type weakref_type;//相当于typedef RefBase::weakref_type weakref_typ sp(T* other); sp(const sp<T>& other); ~sp(); inline T* get() const { return m_ptr; }private: template<typename Y> friend class wp;//wp可以操作sp的私有变量,如构造函数 sp(T* p, weakref_type* refs); T* m_ptr;};// ---------------------------------------------------------------------------template <typename T>class wp{public:typedef RefBase::weakref_type weakref_type; wp(T* other); wp(const wp<T>& other); ~wp(); sp<T> promote() const; inline weakref_type* get_refs() const { return m_refs; }private: T* m_ptr;//strongPointer weakref_type* m_refs;//weakref_impl};// ---------------------------------------------------------------------------template<typename T>sp<T>::sp(T* other) : m_ptr(other)//strongPointer{ if (other) other->incStrong(this);}template<typename T>sp<T>::sp(const sp<T>& other) : m_ptr(other.m_ptr){ if (m_ptr) m_ptr->incStrong(this);}template<typename T>sp<T>::~sp(){ if (m_ptr) m_ptr->decStrong(this);}template<typename T>sp<T>::sp(T* p, weakref_type* refs) : m_ptr((p && refs->attemptIncStrong(this)) ? p : 0){}// ---------------------------------------------------------------------------template<typename T>wp<T>::wp(T* other) : m_ptr(other)//strongPointer{ if (other) m_refs = other->createWeak(this);//weakref_impl}template<typename T>wp<T>::wp(const wp<T>& other) : m_ptr(other.m_ptr), m_refs(other.m_refs){ if (m_ptr) m_refs->incWeak(this);}template<typename T>wp<T>::~wp(){ if (m_ptr) m_refs->decWeak(this);}template<typename T>sp<T> wp<T>::promote() const{ return sp<T>(m_ptr, m_refs);}
二、RefBase.cpp
#include "RefBase.h"#include <iostream>using namespace std;#define INITIAL_STRONG_VALUE (1<<28)class RefBase::weakref_impl : public RefBase::weakref_type{public: volatile int mStrong; volatile int mWeak; RefBase* const mBase; volatile int mFlags; weakref_impl(RefBase* base) : mStrong(INITIAL_STRONG_VALUE) , mWeak(0) , mBase(base) , mFlags(0) { } ~weakref_impl() { cout << "~weakref_impl"<<endl; }};// ---------------------------------------------------------------------------void RefBase::incStrong(const void* id) const{ weakref_impl* const refs = mRefs; refs->incWeak(id); const int c = refs->mStrong++; if (c != INITIAL_STRONG_VALUE) { return; } refs->mStrong = refs->mStrong - INITIAL_STRONG_VALUE;}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);}int RefBase::getStrongCount() const{ return mRefs->mStrong;}RefBase* RefBase::weakref_type::refBase() const{ return static_cast<const weakref_impl*>(this)->mBase;}void RefBase::weakref_type::incWeak(const void* id){ weakref_impl* const impl = static_cast<weakref_impl*>(this); impl->mWeak++;}void RefBase::weakref_type::decWeak(const void* id){ weakref_impl* const impl = static_cast<weakref_impl*>(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<weakref_impl*>(this); int curCount = impl->mStrong; if (curCount > 0 && curCount != INITIAL_STRONG_VALUE) {//mStrong变化过,且大于0 impl->mStrong = curCount + 1; curCount = impl->mStrong; } if (curCount <= 0 || curCount == INITIAL_STRONG_VALUE) {//mStrong没有变化过;或者变化后,为0 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<const weakref_impl*>(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<weakref_impl*>(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<weakref_impl*>(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 + 1) {impl->mStrong = impl->mStrong - INITIAL_STRONG_VALUE; } return true;}
if (curCount > 0 && curCount != INITIAL_STRONG_VALUE) { impl->mStrong = curCount + 1; curCount = impl->mStrong; }
如果此时强引用计数不为0,或者初始值,那么说明RefBase及其子类还没有删除,所以可以提升为强引用
allow = (impl->mFlags&OBJECT_LIFETIME_WEAK) == OBJECT_LIFETIME_WEAK && impl->mBase->onIncStrongAttempted(FIRST_INC_STRONG, id);
如果此时强引用计数为0,并且还受强指针控制,那么此时,RefBase及其子类已经被删除了,所以不能提升为强引用
如果此时强引用计数为0,并且还受弱指针控制,那么此时,RefBase及其子类还没有删除,能不能提升就看impl->mBase->onIncStrongAttempted(FIRST_INC_STRONG, id)的了
allow = (impl->mFlags&OBJECT_LIFETIME_WEAK) != OBJECT_LIFETIME_WEAK || impl->mBase->onIncStrongAttempted(FIRST_INC_STRONG, id);
如果此时强引用计数为INITIAL_STRONG_VALUE,并且还受强指针控制,此时RefBase及其子类还没有删除,所以能够提升。
如果此时强引用计数为INITIAL_STRONG_VALUE,并且还受弱指针控制,此时RefBase及其子类还没有删除,能不能提升就看impl->mBase->onIncStrongAttempted(FIRST_INC_STRONG, id)的了
三、main.cpp
#include <stdio.h>#include "RefBase.h"#define INITIAL_STRONG_VALUE (1<<28)class WeightClass: public RefBase {public:void printRefCount() {int strong = getStrongCount();weakref_type* ref = getWeakRefs();printf("-----------------------\n");printf("Strong Ref Count: %d.\n",(strong == INITIAL_STRONG_VALUE ? 0 : 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");}};class ForeverClass: public WeightClass {public:ForeverClass() {extendObjectLifetime(OBJECT_LIFETIME_FOREVER);printf("Construct ForeverClass Object.\n");}virtual ~ForeverClass() {printf("Destory ForeverClass Object.\n");}};void TestStrongClass(StrongClass* pStrongClass) {wp<StrongClass> wpOut = pStrongClass;pStrongClass->printRefCount();{sp<StrongClass> spInner = pStrongClass;pStrongClass->printRefCount();}pStrongClass->printRefCount();sp<StrongClass> spOut = wpOut.promote();printf("spOut: %p.\n", spOut.get());pStrongClass->printRefCount();}void TestStrongClass2(StrongClass* pStrongClass) {wp<StrongClass> wpOut = pStrongClass;pStrongClass->printRefCount();}void TestStrongClass4(StrongClass* pStrongClass) {wp<StrongClass> wpOut = pStrongClass;pStrongClass->printRefCount();sp<StrongClass> spInner = pStrongClass;pStrongClass->printRefCount();sp<StrongClass> spOut = wpOut.promote();printf("spOut: %p.\n", spOut.get());pStrongClass->printRefCount();}void TestStrongClass3(StrongClass* pStrongClass) {wp<StrongClass> wpOut = pStrongClass;pStrongClass->printRefCount();sp<StrongClass> spOut = wpOut.promote();printf("spOut: %p.\n", spOut.get());pStrongClass->printRefCount();}void TestWeakClass(WeakClass* pWeakClass) {wp<WeakClass> wpOut = pWeakClass;pWeakClass->printRefCount();{sp<WeakClass> spInner = pWeakClass;pWeakClass->printRefCount();}pWeakClass->printRefCount();sp<WeakClass> spOut = wpOut.promote();printf("spOut: %p.\n", spOut.get());pWeakClass->printRefCount();}void TestForeverClass(ForeverClass* pForeverClass) {wp<ForeverClass> wpOut = pForeverClass;pForeverClass->printRefCount();{sp<ForeverClass> spInner = pForeverClass;pForeverClass->printRefCount();}pForeverClass->printRefCount();}int main(int argc, char** argv) {/* printf("Test Strong Class: \n"); StrongClass* pStrongClass = new StrongClass(); TestStrongClass(pStrongClass);*//* printf("Test Strong Class2: \n"); StrongClass* pStrongClass = new StrongClass(); TestStrongClass2(pStrongClass);*//* printf("\nTest Weak Class: \n"); WeakClass* pWeakClass = new WeakClass(); TestWeakClass(pWeakClass);*//* printf("\nTest Froever Class: \n"); ForeverClass* pForeverClass = new ForeverClass(); TestForeverClass(pForeverClass); pForeverClass->printRefCount(); delete pForeverClass;*//* printf("Test Strong Class3: \n"); StrongClass* pStrongClass = new StrongClass(); TestStrongClass3(pStrongClass);*/printf("Test Strong Class4: \n");StrongClass* pStrongClass = new StrongClass();TestStrongClass4(pStrongClass);return 0;}
四、运行结果
第一个:
Test Strong Class:
Construct StrongClass Object.
-----------------------
Strong Ref Count: 0.
Weak Ref Count: 1.
-----------------------
-----------------------
Strong Ref Count: 1.
Weak Ref Count: 2.
-----------------------
Destory StrongClass Object.
-----------------------
Strong Ref Count: 0.
Weak Ref Count: 1.
-----------------------
spOut: (nil).
-----------------------
Strong Ref Count: 0.
Weak Ref Count: 1.
-----------------------
~weakref_impl
第二个:
Test Strong Class2:
Construct StrongClass Object.
-----------------------
Strong Ref Count: 0.
Weak Ref Count: 1.
-----------------------
Destory StrongClass Object.
~weakref_impl
第三个:
Test Weak Class:
Construct WeakClass Object.
-----------------------
Strong Ref Count: 0.
Weak Ref Count: 1.
-----------------------
-----------------------
Strong Ref Count: 1.
Weak Ref Count: 2.
-----------------------
-----------------------
Strong Ref Count: 0.
Weak Ref Count: 1.
-----------------------
spOut: 0x1d60010.
-----------------------
Strong Ref Count: 1.
Weak Ref Count: 2.
-----------------------
Destory WeakClass Object.
~weakref_impl
第四个:
Test Froever Class:
Construct ForeverClass Object.
-----------------------
Strong Ref Count: 0.
Weak Ref Count: 1.
-----------------------
-----------------------
Strong Ref Count: 1.
Weak Ref Count: 2.
-----------------------
-----------------------
Strong Ref Count: 0.
Weak Ref Count: 1.
-----------------------
-----------------------
Strong Ref Count: 0.
Weak Ref Count: 0.
-----------------------
Destory ForeverClass Object.
~weakref_impl
第五个:
Test Strong Class3:
Construct StrongClass Object.
-----------------------
Strong Ref Count: 0.
Weak Ref Count: 1.
-----------------------
spOut: 0x646010.
-----------------------
Strong Ref Count: 1.
Weak Ref Count: 2.
-----------------------
Destory StrongClass Object.
~weakref_impl
第六个:
Test Strong Class4:
Construct StrongClass Object.
-----------------------
Strong Ref Count: 0.
Weak Ref Count: 1.
-----------------------
-----------------------
Strong Ref Count: 1.
Weak Ref Count: 2.
-----------------------
spOut: 0x154e010.
-----------------------
Strong Ref Count: 2.
Weak Ref Count: 3.
-----------------------
Destory StrongClass Object.
~weakref_impl
- c++:智能指针
- C++:智能指针
- 【C++】智能指针
- 【C++】智能指针
- C++PJ智能指针
- 【c++】智能指针
- 【C++】智能指针auto_ptr
- C++,智能指针
- C++,boost智能指针
- 智能指针模拟C
- [C++]智能指针
- 【C++】 浅析智能指针
- C++_智能指针
- C++:初识智能指针
- C++::智能指针
- 【C++】智能指针
- c智能指针:unique_ptr
- 【C++】智能指针
- OpenGL学习十四:光照1
- ESXI 5.5的搭建以及VMware9.0的虚拟机移植
- Handler整理
- 谁动了我的cpu——oprofile使用札记
- IE9 table显示问题,td出现错位的解决方法
- C++ 智能指针
- ASP.NET中的URL编码解码
- repeater全选
- oracle 日期格式
- 安卓入门:动态输入日期与时间
- Oracle一些接口表的使用方法
- shell脚本变量与参数
- UIImage常用的分类
- table表格内容过多时中自动换行