我的智能指针

#pragma once

class KRYPtrCount
{
public:
    KRYPtrCount() :shared_count(1), weak_count(0){}
    void addShared(){ shared_count += 1; }
    void addWeak(){ weak_count += 1; }
    void subShared(){ shared_count -= 1; }
    void subWeak(){ weak_count -= 1; }
public:
    int shared_count;
    int weak_count;
};

template<typename T>
class KRYRefPtr
{
    template<typename U>
    friend class KRYRefPtr;
    template<typename U>
    friend class KRYWeakPtr;
private:
    void subShared()
    {
        if (0 != m_count)
        {
            m_count->shared_count -= 1;
            if (m_count->shared_count <= 0)
            {
                delete m_ptr; m_ptr = 0;
                if (m_count->weak_count <= 0)
                {
                    delete m_count;
                    m_count = 0;
                }
            }
        }
    }
    template<typename U>
    void init(const U *ptr)
    {
        m_ptr = (U*)ptr; m_count = 0;
        if (0 != ptr){ m_count = new KRYPtrCount(); }
    }
    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->addShared(); }
    }
    template<typename U>
    void reset(const U *ptr)
    {
        subShared();
        m_ptr = (U*)ptr; m_count = 0;
        if (0 != ptr){ m_count = new KRYPtrCount(); }
    }
    template<typename U>
    void reset(const KRYRefPtr<U> &ptr)
    {
        if (0 != ptr.m_count){ ptr.m_count->addShared(); }
        subShared();
        m_ptr = ptr.m_ptr;
        m_count = ptr.m_count;
    }
    template<typename U>
    KRYRefPtr(U *ptr, KRYPtrCount *count)
    {
        m_ptr = 0; m_count = 0;
        if (0 != count && count->shared_count > 0)
        {
            m_ptr = ptr; m_count = count;
            m_count->addShared();
        }
    }
public:
    KRYRefPtr(){ m_ptr = 0; m_count = 0; }
    ~KRYRefPtr() { subShared(); }
    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(){ subShared(); m_ptr = 0; m_count = 0; }
private:
    T *m_ptr;
    KRYPtrCount *m_count;
};
template<typename T>
class KRYWeakPtr
{
    template<typename U>
    friend class KRYWeakPtr;
private:
    void subWeak()
    {
        if (0 != m_count)
        {
            m_count->weak_count -= 1;
            if (m_count->shared_count <= 0 && m_count->weak_count <= 0)
            {
                delete m_count;
                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->addWeak(); }
    }
    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->addWeak(); }
    }
    template<typename U>
    void reset(const KRYWeakPtr<U> &ptr)
    {
        if (0 != ptr.m_count){ ptr.m_count->addWeak(); }
        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->addWeak(); }
        subWeak();
        m_ptr = ptr.m_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(const KRYRefPtr<U> &ptr) { init(ptr); }

    template<typename U>
    KRYWeakPtr& operator=(const KRYWeakPtr<U> &ptr) { reset(ptr); return *this; }
    template<typename U>
    KRYWeakPtr& operator=(const KRYRefPtr<U> &ptr) { reset(ptr); return *this; }

    KRYRefPtr<T> lock()const{ return KRYRefPtr<T>(m_ptr, m_count); }
    operator bool() const { return 0 != m_count && m_count->shared_count > 0; }
    T* getPtr()const
    {
        T* ptr = 0;
        if (0 != m_count && m_count->shared_count > 0) { ptr = m_ptr; }
        return ptr;
    }
private:
    T *m_ptr;
    KRYPtrCount *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()); }

 

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