Вот самодельный 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__