thread safe smart_pointer
От: makes Россия  
Дата: 28.08.09 21:35
Оценка:
Вот самодельный thread safe smart pointer
для polymorphic классов без встроенного счетчика ссылок.

Просьба указать на потенциальные ошибки, возможности оптимизации и т.д., в общем оценить и покритиковать.


#ifndef __SMART_POINTER__
#define __SMART_POINTER__
#pragma once


#include <map>
#include <iostream>
#include <windows.h>


// smartptr_base ======================================
class smartptr_base
{
public:
    typedef std::map<const void*,int> register_type;

    static register_type& reg()
    {
        static register_type reg;
        return reg;
    }

    static CRITICAL_SECTION *pcs()
    {
        static CRITICAL_SECTION *pcs = 0;
        if ( !pcs )
        {
            pcs = new CRITICAL_SECTION;
            ::InitializeCriticalSection(pcs);
        }
        return pcs;
    }

    static void lock()
    {
        ::EnterCriticalSection(pcs());
    }

    static void unlock()
    {
        ::LeaveCriticalSection(pcs());
    }

    static int increase_refcount(const void *pt)
    {
        lock();

        int refcnt = ++reg()[pt];

        unlock();
        return refcnt;
    }

    static int decrease_refcount(const void *pt)
    {
        lock();
        int refcnt = --reg()[pt];

        if ( !refcnt )
            reg().erase(pt);

        unlock();
        return refcnt;
    }
};

// smartptr =================================================
template<class T>
class smartptr : smartptr_base
{
public:
    typedef T element_type;

    /*explicit*/ smartptr(const T *pt = 0)
        : m_pt( 0 ) //init member to zero!
    {
        reset( pt );
    }

    template<class U>
    /*explicit*/ smartptr(const U *pu)
        : m_pt( 0 ) //init member to zero!
    {
        reset( dynamic_cast<const T*>(pu) );
    }

    smartptr(const smartptr& sp)
        : m_pt( 0 ) //init member to zero!
    {
        reset( sp.m_pt );
    }

    template<class U>
    smartptr(const smartptr<U>& sp)
        : m_pt( 0 ) //init member to zero!
    {
        reset( dynamic_cast<const T*>(sp.get()) );
    }

    ~smartptr()
    {
        reset();
    }

    smartptr& reset(const T *pt = 0)
    {
        if ( m_pt == pt )
            return *this;

        if ( m_pt && !decrease_refcount(dynamic_cast<const void*>(m_pt)) )
            delete m_pt;

        if ( pt )
            increase_refcount(dynamic_cast<const void*>(pt));

        m_pt = pt;
        return *this;
    }

    // standard operations ----------------------------------------------
          T *get               ()       { return const_cast<T*>(m_pt); }
    const T *get               () const { return m_pt; }
             operator       T* ()       { return  get(); }
             operator const T* () const { return  get(); }
          T& operator *        ()       { return *get(); }
    const T& operator *        () const { return *get(); }
          T *operator ->       ()       { return  get(); }
    const T *operator ->       () const { return  get(); }

             operator bool     () const { return m_pt ? true  : false; }
    bool     operator !        () const { return !(bool)(*this); }

    smartptr& operator = (const smartptr& sp)
    {
        return reset( sp.get() );
    }

    template<class U>
    smartptr& operator = (const smartptr<U>& sp)
    {
        return reset( dynamic_cast<const T*>(sp.get()) );
    }

private:
    const T *m_pt;
};

#endif//__SMART_POINTER__
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.