Click here to Skip to main content
15,892,839 members
Articles / Programming Languages / C++

TAutoPtr<TYPE, CLEANUPOBJECT>

Rate me:
Please Sign up or sign in to vote.
3.00/5 (1 vote)
29 Aug 20014 min read 66.1K   909   17  
Automatic resource deallocation using TAutoPtr<TYPE, CLEANUPOBJECT>
#ifndef __TAutoPtr_H__
#define __TAutoPtr_H__
/////////////////////////////////////////////////////////////////////////////
//
// An extension of std::auto_ptr<> class from the Standard Template Library.
//
// This is the multi-purpose template class for automatic resource cleaning.
// You can easily customize it for your concrete need by defining your own
// CLEANUPOBJECT.
//
/////////////////////////////////////////////////////////////////////////////
//
// (c) 1999-2001, Dmitry Leonov, Moscow, dmitry.leonov@mtu-net.ru
//
// This file is provided "AS IS" with no expressed or implied warranty.
// The author accepts no liability for any damage/loss of data or business
// that this product may cause.
//
// This code may be used in compiled form in any way you desire. This
// file may be redistributed unmodified by any means providing it is
// not sold for profit without the authors written consent, and
// providing that this notice and the authors name and all copyright
// notices remains intact.
//
// Please let me know of any bugs/modifications/improvements
// that you have found/implemented.
//
/////////////////////////////////////////////////////////////////////////////
//
// History:
//
// 990923dl: This code was first published on GodeGuru Discussions.
// 000105dl: This code is posted on GodeGuru.
// 000525dl: Now a C++ functional object (like std::unary_function<>) is used
//           instead of old cleanup function. The main advantage of this is
//           the type of the deallocating resource is always known. You now
//           deal with TYPE* inside your CLEANUPOBJECT (instead of void*).
//           Note that from this moment the code become incompatible to the
//           previous AutoPtr implementation. To avoid collisions the new
//           version is called TAutoPtr.
// 010814dl: Ready to a new publication.
//
/////////////////////////////////////////////////////////////////////////////



/////////////////////////////////////////////////////////////////////////////
//
// About CEANUPOBJECT: it must support std::unary_function concept.
//
// Example of CLEANUPOBJECT:
//
// template<typename TYPE>
// struct SDeleteSingle
// {
//     void operator()(TYPE* p)
//     {
//         if(p)
//             delete p;
//     }
// };
//
// Example of type declaration:
// typedef TAutoPtr<CSomeClass, SDeleteSingle<CSomeClass> > TSomeClassAutoPtr;
//
/////////////////////////////////////////////////////////////////////////////



//Uncomment the next line if you don't want to see a tiresome VC++ warning.
//#pragma warning(disable: 4284)



template<typename TYPE, typename CLEANUPOBJECT>
class TAutoPtr
{
private:


    TAutoPtr(const TAutoPtr& c);
    TAutoPtr& operator=(const TAutoPtr& c);


public:


    typedef TAutoPtr<TYPE, CLEANUPOBJECT>   __TAutoPtr;


    //Standard constructor
    explicit TAutoPtr(TYPE* p = 0) : m_bOwns(0 != p), m_p(p)
    {
    }


    //Assignment operator
    TAutoPtr& operator=(TYPE* p)
    {
        if(Get() != p)
        {
            Free();
            m_bOwns = (0 != p);
            m_p = p;
        }
        return *this;
    }


    //The destructor
    ~TAutoPtr()
    {
        Free();
    }


    //Type casting
    operator TYPE*() const
    {
        return Get();
    }


    //Dereference operator
    TYPE& operator*() const
    {
        return *Get();
    }


    //Logical NOT
    bool operator!() const
    {
        return 0 == Get();
    }


    //Member selection (pointer)
    TYPE* operator->() const
    {
        return Get();
    }


    //Clears the responsibility flag.
    //Use this method when you neet to forget about resource cleaning explicitly.
    TYPE* Forget() const
    {
        m_bOwns = false;
        return Get();
    }


    //Safe pointer
    TYPE* Get() const
    {
        return m_p;
    }


    //For functions taking a pointer as an argument by a reference.
    //std::auto_ptr<> haven't got this feature.
    TYPE*& ByRef(bool bOwns = true)
    {
        Clear(bOwns);
        return m_p;
    }


    //For functions taking a pointer as an argument by a pointer.
    //std::auto_ptr<> haven't got this feature.
    TYPE** ByPtr(bool bOwns = true)
    {
        Clear(bOwns);
        return &m_p;
    }


    //Frees the pointer and then initializes members
    void Clear(bool bOwns = false)
    {
        Free();
        m_bOwns = bOwns;
        m_p = 0;
    }


private:


    //Responsibility flag for resource cleaning
    mutable bool    m_bOwns;


    //Pointer to controlled resource
    TYPE*           m_p;


    //Frees the pointer without members initialization
    void Free()
    {
        if(m_bOwns)
        {
            CLEANUPOBJECT()(m_p);
        }
    }


};



/////////////////////////////////////////////////////////////////////////////
#endif //__TAutoPtr_H__

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


Written By
Web Developer
Russian Federation Russian Federation
VC++, MFC, ODBC, OLEDB
Python
Perl
XML
AutoCAD R<=14.0 ObjectARX, AutoLISP

Comments and Discussions