我的另一个智能指针
KRYObject.h
#pragma once class KRYObject { template<typename T> friend class KRYRefPtr; template<typename T> friend class KRYWeakPtr; private: struct KRYRefCount { KRYRefCount() { //able = true; refCount = 0; weakCount = 1; } //bool able; int refCount; int weakCount; }; protected: KRYObject() { m_count = 0; } virtual ~KRYObject() { if (0 != m_count) { //m_count->able = false; m_count->weakCount -= 1; if (m_count->refCount <= 0 && m_count->weakCount <= 0) { delete m_count; m_count = 0; } } } inline void addRef() { m_count->refCount += 1; } inline KRYRefCount* subRef() { KRYRefCount *ret = m_count; m_count->refCount -= 1; if (m_count->refCount <= 0) { ret = 0; delete this; } return ret; } private: inline KRYRefCount* getCount()const { if (0 == m_count) { m_count = new KRYRefCount(); } return m_count; } private: mutable KRYRefCount *m_count; }; template<typename T> class KRYRefPtr { template<typename U> friend class KRYRefPtr; template<typename U> friend class KRYWeakPtr; private: void subRef() { if (0 != m_count) { m_count = m_ptr->subRef(); if (0 == m_count) { m_ptr = 0; m_count = 0; } } } template<typename U> void init(const U *ptr) { m_ptr = (U*)ptr; m_count = 0; if (0 != m_ptr){ m_count = ptr->getCount(); m_count->refCount += 1; } } template<typename U> void init(const KRYRefPtr<U> &ptr) { m_ptr = ptr.m_ptr; m_count = ptr.m_count; if (0 != m_count){ m_count->refCount += 1; } } template<typename U> void reset(const U *ptr) { if (0 != ptr){ ptr->getCount()->refCount += 1; } subRef(); m_ptr = (U*)ptr; m_count = 0; if (0 != ptr){ m_count = ptr->m_count; } } template<typename U> void reset(const KRYRefPtr<U> &ptr) { if (0 != ptr.m_count){ ptr.m_count->refCount += 1; } subRef(); m_ptr = ptr.m_ptr; m_count = ptr.m_count; } template<typename U> KRYRefPtr(U *ptr, KRYObject::KRYRefCount *count) { m_ptr = 0; m_count = 0; if (0 != count && count->refCount > 0) { m_ptr = ptr; m_count = count; m_count->refCount += 1; } } public: KRYRefPtr(){ m_ptr = 0; m_count = 0; } ~KRYRefPtr() { subRef(); } KRYRefPtr(const KRYRefPtr& ptr) { init(ptr); } KRYRefPtr operator=(const KRYRefPtr& ptr) { reset(ptr); return *this; } template<typename U> KRYRefPtr(U *ptr) { init(ptr); } template<typename U> KRYRefPtr<T>& operator=(U *ptr) { reset(ptr); return *this; } template<typename U> KRYRefPtr(const KRYRefPtr<U> &ptr) { init(ptr); } template<typename U> KRYRefPtr<T>& operator=(const KRYRefPtr<U> &ptr) { reset(ptr); return *this; } T* operator->() const{ return m_ptr; } T& operator*() const { return *m_ptr; } operator bool() const { return m_ptr != 0; } T* getPtr() const { return m_ptr; } void reset(){ subRef(); m_ptr = 0; m_count = 0; } private: T *m_ptr; KRYObject::KRYRefCount *m_count; }; template<typename T> class KRYWeakPtr { template<typename U> friend class KRYWeakPtr; private: void subWeak() { if (0 != m_count) { m_count->weakCount -= 1; if (m_count->refCount <= 0 && m_count->weakCount <= 0) { delete m_count; m_ptr = 0; m_count = 0; } } } template<typename U> void init(const KRYWeakPtr<U> &ptr) { m_ptr = ptr.m_ptr; m_count = ptr.m_count; if (0 != m_count){ m_count->weakCount += 1; } } template<typename U> void init(const KRYRefPtr<U> &ptr) { m_ptr = ptr.m_ptr; m_count = ptr.m_count; if (0 != m_count){ m_count->weakCount += 1; } } template<typename U> void init(const U *ptr) { m_ptr = (U*)ptr; m_count = 0; if (0 != ptr){ m_count = ptr->getCount(); m_count->weakCount += 1; } } template<typename U> void reset(const KRYWeakPtr<U> &ptr) { if (0 != ptr.m_count){ ptr.m_count->weakCount += 1; } subWeak(); m_ptr = ptr.m_ptr; m_count = ptr.m_count; } template<typename U> void reset(const KRYRefPtr<U> &ptr) { if (0 != ptr.m_count){ ptr.m_count->weakCount += 1; } subWeak(); m_ptr = ptr.m_ptr; m_count = ptr.m_count; } template<typename U> void reset(const U *ptr) { if (0 != ptr){ ptr->getCount()->weakCount += 1; } subWeak(); m_ptr = ptr; m_count = 0; if (0 != ptr){ m_count = ptr->m_count;} } public: KRYWeakPtr(){ m_ptr = 0; m_count = 0; } ~KRYWeakPtr(){ subWeak(); } KRYWeakPtr(const KRYWeakPtr &ptr) { init(ptr); } KRYWeakPtr& operator=(const KRYWeakPtr &ptr) { reset(ptr); return *this; } template<typename U> KRYWeakPtr(const KRYWeakPtr<U> &ptr) { init(ptr); } template<typename U> KRYWeakPtr& operator=(const KRYWeakPtr<U> &ptr) { reset(ptr); return *this; } template<typename U> KRYWeakPtr(const KRYRefPtr<U> &ptr) { init(ptr); } template<typename U> KRYWeakPtr& operator=(const KRYRefPtr<U> &ptr) { reset(ptr); return *this; } template<typename U> KRYWeakPtr(const U *ptr) { init(ptr); } template<typename U> KRYWeakPtr& operator=(const U *ptr) { reset(ptr); return *this; } KRYRefPtr<T> lock() { return KRYRefPtr<T>(m_ptr, m_count); } T* operator->() const{ return m_ptr; } T& operator*() const { return *m_ptr; } //operator bool() const { return m_count != 0 && m_count->able; } operator bool() const { return m_count != 0 && m_count->refCount > 0; } T* getPtr() const { T *ptr = 0; //if (m_count != 0 && m_count->able) if (m_count != 0 && m_count->refCount > 0) { ptr = m_ptr; } return ptr; } void reset(){ subWeak(); m_ptr = 0; m_count = 0; } private: T *m_ptr; KRYObject::KRYRefCount *m_count; }; template<typename T, typename U> bool operator==(const KRYRefPtr<T>& a, const KRYRefPtr<U>& b) { return (a.getPtr() == b.getPtr()); } template<typename T, typename U> bool operator==(const KRYRefPtr<T>& a, const U* b) { return (a.getPtr() == b); } template<typename T, typename U> bool operator==(const U* a, const KRYRefPtr<T>& b) { return (a == b.getPtr()); } template<typename T, typename U> bool operator!=(const KRYRefPtr<T>& a, const KRYRefPtr<U>& b) { return (a.getPtr() != b.getPtr()); } template<typename T, typename U> bool operator!=(const KRYRefPtr<T>& a, const U* b) { return (a.getPtr() != b); } template<typename T, typename U> bool operator!=(const U* a, const KRYRefPtr<T>& b) { return (a != b.getPtr()); } template<typename T, typename U> bool operator==(const KRYWeakPtr<T>& a, const KRYWeakPtr<U>& b) { return (a.getPtr() == b.getPtr()); } template<typename T, typename U> bool operator==(const KRYWeakPtr<T>& a, const U* b) { return (a.getPtr() == b); } template<typename T, typename U> bool operator==(const U* a, const KRYWeakPtr<T>& b) { return (a == b.getPtr()); } template<typename T, typename U> bool operator!=(const KRYWeakPtr<T>& a, const KRYWeakPtr<U>& b) { return (a.getPtr() != b.getPtr()); } template<typename T, typename U> bool operator!=(const KRYWeakPtr<T>& a, const U* b) { return (a.getPtr() != b); } template<typename T, typename U> bool operator!=(const U* a, const KRYWeakPtr<T>& b) { return (a != b.getPtr()); }
test.cpp
#include "KRYObject.h" class Base:public KRYObject { public: Base(){ cout << "Base()" << endl; } virtual ~Base(){ cout << "~Base()" << endl; } virtual void fun(){ cout << "Base::fun()" << endl; } }; class Device :public Base { public: Device(){ cout << "Device()" << endl; } ~Device(){ cout << "~Device()" << endl; } virtual void fun(){ cout << "Device::fun()" << endl; } }; void main() { /*KRYRefPtr<Device> device = new Device(); { KRYRefPtr<Base> base = device; base->fun(); } device->fun();*/ KRYWeakPtr<Base> weak; { KRYRefPtr<Device> device = new Device(); weak = device; } if (weak){ weak->fun(); } }