我的另一个智能指针

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(); }
}

 

posted @ 2015-10-15 20:34  liusijian  阅读(159)  评论(0编辑  收藏  举报