关于引用计数一点点归纳

大凡大一点的开源程序都会看到用引用计数的相关技术,粗略看一下有两种实现方式:

1. 计数器在类的基类中,并提供增加和减少计数的函数,用模板来实现引用计数,看到大部分的常用指针都是使用的继承方式来实现,如下面的代码,这个模板类的T必须要实现ref()和dref(),而且必须包含计数器 (摘的webkit的),T的类比较复杂,没有粘贴过来

2. 计数器在模板类中,每声明一个模板类会有一个计数器,有多个计数器,在使用的时候有一定的限制,只能通过赋值方式传递,不能通过直接构造方式,如boost::shared_ptr<T>的使用。


template<typename T> class RefPtr {
        WTF_MAKE_FAST_ALLOCATED;
    public:
        ALWAYS_INLINE RefPtr() : m_ptr(0) { }
        ALWAYS_INLINE RefPtr(T* ptr) : m_ptr(ptr) { refIfNotNull(ptr); }
        ALWAYS_INLINE RefPtr(const RefPtr& o) : m_ptr(o.m_ptr) { refIfNotNull(m_ptr); }
        template<typename U> RefPtr(const RefPtr<U>& o) : m_ptr(o.get()) { refIfNotNull(m_ptr); }


        // See comments in PassRefPtr.h for an explanation of why this takes a const reference.
        template<typename U> RefPtr(const PassRefPtr<U>&);


        // Special constructor for cases where we overwrite an object in place.
        ALWAYS_INLINE RefPtr(PlacementNewAdoptType) { }


        // Hash table deleted values, which are only constructed and never copied or destroyed.
        RefPtr(HashTableDeletedValueType) : m_ptr(hashTableDeletedValue()) { }
        bool isHashTableDeletedValue() const { return m_ptr == hashTableDeletedValue(); }


        ALWAYS_INLINE ~RefPtr() { derefIfNotNull(m_ptr); }


        T* get() const { return m_ptr; }
        
        void clear();
        PassRefPtr<T> release() { PassRefPtr<T> tmp = adoptRef(m_ptr); m_ptr = 0; return tmp; }


        T& operator*() const { return *m_ptr; }
        ALWAYS_INLINE T* operator->() const { return m_ptr; }
        
        bool operator!() const { return !m_ptr; }
    
        // This conversion operator allows implicit conversion to bool but not to other integer types.
        typedef T* (RefPtr::*UnspecifiedBoolType);
        operator UnspecifiedBoolType() const { return m_ptr ? &RefPtr::m_ptr : 0; }
        
        RefPtr& operator=(const RefPtr&);
        RefPtr& operator=(T*);
        RefPtr& operator=(const PassRefPtr<T>&);
#if !COMPILER_SUPPORTS(CXX_NULLPTR)
        RefPtr& operator=(std::nullptr_t) { clear(); return *this; }
#endif
        template<typename U> RefPtr& operator=(const RefPtr<U>&);
        template<typename U> RefPtr& operator=(const PassRefPtr<U>&);


        void swap(RefPtr&);


        static T* hashTableDeletedValue() { return reinterpret_cast<T*>(-1); }


    private:
        T* m_ptr;
    };
    
    template<typename T> template<typename U> inline RefPtr<T>::RefPtr(const PassRefPtr<U>& o)
        : m_ptr(o.leakRef())
    {
    }


    template<typename T> inline void RefPtr<T>::clear()
    {
        T* ptr = m_ptr;
        m_ptr = 0;
        derefIfNotNull(ptr);
    }


    template<typename T> inline RefPtr<T>& RefPtr<T>::operator=(const RefPtr<T>& o)
    {
        T* optr = o.get();
        refIfNotNull(optr);
        T* ptr = m_ptr;
        m_ptr = optr;
        derefIfNotNull(ptr);
        return *this;
    }
    
    template<typename T> template<typename U> inline RefPtr<T>& RefPtr<T>::operator=(const RefPtr<U>& o)
    {
        T* optr = o.get();
        refIfNotNull(optr);
        T* ptr = m_ptr;
        m_ptr = optr;
        derefIfNotNull(ptr);
        return *this;
    }
    
    template<typename T> inline RefPtr<T>& RefPtr<T>::operator=(T* optr)
    {
        refIfNotNull(optr);
        T* ptr = m_ptr;
        m_ptr = optr;
        derefIfNotNull(ptr);
        return *this;
    }


    template<typename T> inline RefPtr<T>& RefPtr<T>::operator=(const PassRefPtr<T>& o)
    {
        T* ptr = m_ptr;
        m_ptr = o.leakRef();
        derefIfNotNull(ptr);
        return *this;
    }


    template<typename T> template<typename U> inline RefPtr<T>& RefPtr<T>::operator=(const PassRefPtr<U>& o)
    {
        T* ptr = m_ptr;
        m_ptr = o.leakRef();
        derefIfNotNull(ptr);
        return *this;
    }


    template<class T> inline void RefPtr<T>::swap(RefPtr<T>& o)
    {
        std::swap(m_ptr, o.m_ptr);
    }


    template<class T> inline void swap(RefPtr<T>& a, RefPtr<T>& b)
    {
        a.swap(b);
    }


    template<typename T, typename U> inline bool operator==(const RefPtr<T>& a, const RefPtr<U>& b)
    { 
        return a.get() == b.get(); 
    }


    template<typename T, typename U> inline bool operator==(const RefPtr<T>& a, U* b)
    { 
        return a.get() == b; 
    }
    
    template<typename T, typename U> inline bool operator==(T* a, const RefPtr<U>& b) 
    {
        return a == b.get(); 
    }
    
    template<typename T, typename U> inline bool operator!=(const RefPtr<T>& a, const RefPtr<U>& b)
    { 
        return a.get() != b.get(); 
    }


    template<typename T, typename U> inline bool operator!=(const RefPtr<T>& a, U* b)
    {
        return a.get() != b; 
    }


    template<typename T, typename U> inline bool operator!=(T* a, const RefPtr<U>& b)
    { 
        return a != b.get(); 
    }
    
    template<typename T, typename U> inline RefPtr<T> static_pointer_cast(const RefPtr<U>& p)
    { 
        return RefPtr<T>(static_cast<T*>(p.get())); 
    }


    template<typename T, typename U> inline RefPtr<T> const_pointer_cast(const RefPtr<U>& p)
    { 
        return RefPtr<T>(const_cast<T*>(p.get())); 
    }


    template<typename T> inline T* getPtr(const RefPtr<T>& p)
    {
        return p.get();
    }


} // namespace WTF

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值