Ogre中的Smart Pointers——SharedPtr

看一下Ogre里面的ShagedPtr,其实就是一个Smart Pointers。下面的代码是删去了原有注释的。现不谈里面的MUTEX。 #ifndef __SharedPtr_H__ #define __SharedPtr_H__ #include "OgrePrerequisites.h" namespace Ogre { template<class T> class SharedPtr { protected: T* pRep; unsigned int* pUseCount; //看到这里,应该能知道,SharedPtr是通过引用计数来管理pRep的寿命 public: OGRE_AUTO_SHARED_MUTEX SharedPtr() : pRep(0), pUseCount(0) { OGRE_SET_AUTO_SHARED_MUTEX_NULL }//允许有一个空的SharedPtr,不指向任何的对象。 template< class Y> explicit SharedPtr(Y* rep) : pRep(rep), pUseCount(new unsigned int(1)) { OGRE_SET_AUTO_SHARED_MUTEX_NULL OGRE_NEW_AUTO_SHARED_MUTEX }//这个写法是Member Templates,很有用,这样就允许用一个Y对象的指针来初始化一个SharedPtr<T> //下面还能看到很多这样的Member Templates //要是以前没见过的人,推荐看一下C++ Templates的第5章、第3节 //try this: vector<int> intvec; // vector<float> floatvec; // floatvec = intvec ??????? //提一下,所有的初始化函数都没有检查rep是否非空,所以SharedPtr接受一个Null指针 //安全检查在每次调用的时候 //这里还使用了关键字explicit,禁止了隐式转换 SharedPtr(const SharedPtr& r) : pRep(0), pUseCount(0) { OGRE_SET_AUTO_SHARED_MUTEX_NULL OGRE_MUTEX_CONDITIONAL(r.OGRE_AUTO_MUTEX_NAME) { OGRE_LOCK_MUTEX(*r.OGRE_AUTO_MUTEX_NAME) OGRE_COPY_AUTO_SHARED_MUTEX(r.OGRE_AUTO_MUTEX_NAME) pRep = r.pRep; //注意下与后面的不同 pUseCount = r.pUseCount; // Handle zero pointer gracefully to manage STL containers if(pUseCount) { ++(*pUseCount); } } } SharedPtr& operator=(const SharedPtr& r) { if (pRep == r.pRep) return *this; SharedPtr<T> tmp(r); swap(tmp); return *this; }//这里的写法有点意思,本来在pRep指向r.pRep之前对pRep做一次release, //但是这里没看到,其实是通过tmp这个局部变量的自动解析实现的。 template< class Y> SharedPtr(const SharedPtr<Y>& r) : pRep(0), pUseCount(0) { OGRE_SET_AUTO_SHARED_MUTEX_NULL OGRE_MUTEX_CONDITIONAL(r.OGRE_AUTO_MUTEX_NAME) { OGRE_LOCK_MUTEX(*r.OGRE_AUTO_MUTEX_NAME) OGRE_COPY_AUTO_SHARED_MUTEX(r.OGRE_AUTO_MUTEX_NAME) pRep = r.getPointer(); //这里用的是函数,和上面那个的区别?? pUseCount = r.useCountPointer(); // Handle zero pointer gracefully to manage STL containers if(pUseCount) { ++(*pUseCount); } } } template< class Y> SharedPtr& operator=(const SharedPtr<Y>& r) { if (pRep == r.pRep) return *this; SharedPtr<T> tmp(r); swap(tmp); return *this; } virtual ~SharedPtr() { release(); } inline T& operator*() const { assert(pRep); return *pRep; } inline T* operator->() const { assert(pRep); return pRep; } //在用的时候检查pRep的合法性 inline T* get() const { return pRep; } void bind(T* rep) { assert(!pRep && !pUseCount); OGRE_NEW_AUTO_SHARED_MUTEX OGRE_LOCK_AUTO_SHARED_MUTEX pUseCount = new unsigned int(1); pRep = rep; } inline bool unique() const { OGRE_LOCK_AUTO_SHARED_MUTEX assert(pUseCount); return *pUseCount == 1; } inline unsigned int useCount() const { OGRE_LOCK_AUTO_SHARED_MUTEX assert(pUseCount); return *pUseCount; } inline unsigned int* useCountPointer() const { return pUseCount; } inline T* getPointer() const { return pRep; } inline bool isNull(void) const { return pRep == 0; } inline void setNull(void) { if (pRep) { // can't scope lock mutex before release incase deleted release(); pRep = 0; pUseCount = 0; } } protected: inline void release(void) { bool destroyThis = false; OGRE_MUTEX_CONDITIONAL(OGRE_AUTO_MUTEX_NAME) { OGRE_LOCK_AUTO_SHARED_MUTEX if (pUseCount) { if (--(*pUseCount) == 0) { destroyThis = true; } } } if (destroyThis) destroy(); OGRE_SET_AUTO_SHARED_MUTEX_NULL } virtual void destroy(void) { delete pRep; delete pUseCount; OGRE_DELETE_AUTO_SHARED_MUTEX } virtual void swap(SharedPtr<T> &other) { std::swap(pRep, other.pRep); std::swap(pUseCount, other.pUseCount); #if OGRE_THREAD_SUPPORT std::swap(OGRE_AUTO_MUTEX_NAME, other.OGRE_AUTO_MUTEX_NAME); #endif } }; template<class T, class U> inline bool operator==(SharedPtr<T> const& a, SharedPtr<U> const& b) { return a.get() == b.get(); } template<class T, class U> inline bool operator!=(SharedPtr<T> const& a, SharedPtr<U> const& b) { return a.get() != b.get(); } } #endif 最后有注意到: inline T* get() const { return pRep; } inline T* getPointer() const { return pRep; } 不知道为啥要这样,有一个不就行了么。 更多的细节、使用方法放到下次把。

你可能感兴趣的:(null,delete,Class,templates,containers,Pointers)