smartptr.h

来自「AUTOCAD 程序员使用的」· C头文件 代码 · 共 235 行

H
235
字号
#ifndef _smartptr_h
#define _smartptr_h

#ifdef T
#undef T
#endif

#define SP_ASSERT(what) if (!(what)) throw "Assertion failed: " #what; else

struct Smart
{
    typedef int Status;
    enum {
        kDoClose       = 1,
        kDontClose     = 2,
    };
};

template <class T>
/////////////////////////////////////////////////////////////////////////////
// class SmartPtr

class 
/*CLASS*/SmartPtr
{
private:

    struct PtrRep
    {
        PtrRep ( T* p )
        : m_ptr( p ), m_flags( Smart::kDoClose ), m_refcount( 1 )
        {  }
        virtual ~PtrRep ()
        {  
            if (NULL != m_ptr && m_flags & Smart::kDoClose)
            {
                if (m_ptr->objectId() != 0)
                    m_ptr->close();
                else
                    delete m_ptr;
            }
        }

        T   *m_ptr;
        int  m_flags;
        int  m_refcount;
    };

    PtrRep *m_rep;

public:
    SmartPtr  ();

#if _MSC_VER >= 1100
    template<class SP>
    SmartPtr  (SmartPtr<SP>& p2)
#else
    SmartPtr  (SmartPtr<T>& p2)
#endif
    {
        SmartPtr<T> *p = (SmartPtr<T>*)&p2;
        if (NULL != T::cast( p->m_rep->m_ptr ))
        {
            m_rep = p->m_rep;
            m_rep->m_refcount++;
        }
        else
            m_rep = new PtrRep( NULL );
    }

    SmartPtr  (const T*);
    virtual ~SmartPtr ();

#if _MSC_VER >= 1100
    template<class SP>
    const SmartPtr<T>& operator=  (const SmartPtr<SP>& p2)
#else
    const SmartPtr<T>& operator=  (const SmartPtr<T>& p2)
#endif
    {
        SmartPtr<T> *p = (SmartPtr<T>*)&p2;
        if (m_rep != p->m_rep)
        {
            if (0 == --m_rep->m_refcount)
                delete m_rep;
            
            if (NULL != T::cast( p->m_rep->m_ptr ))
            {
                m_rep = p->m_rep;
                m_rep->m_refcount++;
            }
            else
                m_rep = new PtrRep( NULL );
        }
        return *this;
    }

    T*                 operator=  (const T*);
    T*&                operator*  ();
    T* const &         operator*  ()      const;
    T*                 operator-> ();
    const T*           operator-> ()      const;

    operator       T* ();
    operator const T* () const;

    void setFlags   (Smart::Status);
};


/****************************************************************************
    SmartPtr::SmartPtr();
        default to NULL
    
    SmartPtr::SmartPtr( const SmartPtr<T> &p2 );
        copy constructor
    
    SmartPtr::SmartPtr( const T *p );
        initialized with address

    SmartPtr::~SmartPtr();
        destructor closes object
    
    const SmartPtr<T>& SmartPtr::operator=( const SmartPtr<T> &p );
    
    T* SmartPtr::operator=( const T *p );
        assigned an address
    
    T*& SmartPtr::operator*();
        unary * (indirection)
    
    const T*& SmartPtr::operator*() const;
        unary * (indirection)

    SmartPtr::operator T*();
        conversion to T*
    
    SmartPtr::operator const T*() const;
        conversion to T*

  T* SmartPtr::operator->();
        -> operator (indirection)
    
    const T* SmartPtr::operator->() const;
        -> operator (indirection)
****************************************************************************/


/////////////////////////////////////////////////////////////////////////////
// SmartPtr Inline functions

template <class T>
inline SmartPtr<T>::SmartPtr()
{
    m_rep = new PtrRep( NULL );
    SP_ASSERT( NULL != m_rep );
}

template <class T>
inline SmartPtr<T>::SmartPtr(const T *p)
{
    m_rep = new PtrRep( (T*)p );
    SP_ASSERT( NULL != m_rep );
}

template <class T>
T* SmartPtr<T>::operator=(const T *p)
{
    if (m_rep->m_ptr == p)
        return m_rep->m_ptr;

    if (0 == --m_rep->m_refcount)
        delete m_rep;
    
    m_rep = new PtrRep( (T*)p );
    SP_ASSERT( NULL != m_rep );
    
    return m_rep->m_ptr;
}

template <class T>
inline T*& SmartPtr<T>::operator*()
{  return m_rep->m_ptr;  }

template <class T>
inline T* const & SmartPtr<T>::operator*() const
{  return m_rep->m_ptr;  }

template <class T>
inline SmartPtr<T>::operator T*()
{  return m_rep->m_ptr;  }

template <class T>
inline SmartPtr<T>::operator const T*() const
{  return m_rep->m_ptr;  }

template <class T>
T* SmartPtr<T>::operator->()
{
    SP_ASSERT( NULL != m_rep->m_ptr );
    return m_rep->m_ptr;
}

template <class T>
const T* SmartPtr<T>::operator->() const
{
    SP_ASSERT( NULL != m_rep->m_ptr );
    return m_rep->m_ptr;
}

template <class T>
SmartPtr<T>::~SmartPtr()
{
    if (0 == --m_rep->m_refcount)
        delete m_rep;
}

template <class T>
void SmartPtr<T>::setFlags( Smart::Status s )
{
    switch (s) {
    case Smart::kDoClose:
        m_rep->m_flags |= Smart::kDoClose;
        break;
    case Smart::kDontClose:
        m_rep->m_flags &= ~Smart::kDoClose;
        break;
    default:
        SP_ASSERT( 1 == 0 );
        break;
    }
}

#endif  // _smartptr_h

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?