Click here to Skip to main content
15,891,846 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 66K   909   17  
Automatic resource deallocation using TAutoPtr<TYPE, CLEANUPOBJECT>
//The demo project for TAutoPtr<>
#include <string.h>
#include <iostream>
#include "autoptr.h"



using namespace std;



//The cleanup object for deleting a single instance pointer.
template<typename TYPE>
struct SDeleteSingle
{
    void operator()(TYPE* p)
    {
        if(p)
        {
            cout << "Automatically release the resource using SDeleteSingle!" << endl;
            delete p;
        }
    }
};



//The cleanup object for deleting an array.
template<typename TYPE>
struct SDeleteArray
{
    void operator()(TYPE* p)
    {
        if(p)
        {
            cout << "Release the resource using SDeleteArray!" << endl;
            delete[] p;
        }
    }
};



//The cleanup object for releasing CMyClass resource and similar
//resources. Similiar means "with the same cleanup interface".
template<typename TYPE>
struct SReleaseInstancePtr
{
    void operator()(TYPE* p)
    {
        TYPE::ReleaseInstancePtr(p);
    }
};



//CMyClass represents the sample resource object.
class CMyClass
{
private:

    CMyClass()  {}
    ~CMyClass() {}

public:

    static bool GetInstancePtr(CMyClass*& p)   //CMyClass class factory.
    {
        cout << "CMyClass::GetInstancePtr()" << endl;

        if(p)
            return false;

        p = new CMyClass;
        return true;
    }

    static void ReleaseInstancePtr(CMyClass*& p)
    {
        cout << "CMyClass::ReleaseInstancePtr()" << endl;

        if(!p)
            return;

        delete p;
        p = 0;
    }

    bool SomeMethod() const
    {
        cout << "CMyClass::SomeMethod()" << endl;
        return true;
    }

};



//The helper typedefs.

//The simple integer value instance manager (a dummy example).
typedef TAutoPtr<int, SDeleteSingle<int> > TIntAutoPtr;

//The simple string instance manager (also dummy example).
typedef TAutoPtr<char, SDeleteArray<char> > TCharArrayAutoPtr;

//The CMyClass instance manager.
typedef TAutoPtr<CMyClass, SReleaseInstancePtr<CMyClass> > TMyClassAutoPtr;



//This sample code uses TAutoPtr<> for automatic
//deallocation the various types of resource.

int main(int argc, char* argv[])
{

    {   //Here we allocate a single integer value. After leaving
        //the scope the dynamic memory will be automatically released
        //when TAutoPtr destructor is called.

        TIntAutoPtr autoInteger( new int(-197) );
        cout << "The Integer resource = " << *autoInteger << endl;

        *autoInteger = 200; //illustrates setting the new value.
        cout << "Now the Integer resource = " << *autoInteger << endl;
    }

    cout << endl;

    {
        char* pCharArray = NULL; //We'll need this pointer

        {   //Here we allocate a simple char array, then assign it the value.
            //Before leaving the scope we call TAutoPtr<>::Forget() function,
            //thes means that TAutoPtr<> will NOT deallocate the memory,
            //so we do this manually just after leaving the scope.

            TCharArrayAutoPtr autoString( new char[64] );
            cout << "Here we use the address " << autoString;
            strcpy(autoString, " to allocate a sample string resource.");
            cout << (char*)autoString << endl;

            //Now tell TAutoPtr don't release the resource in the destructor!
            pCharArray = autoString.Forget();
        }

        delete[] pCharArray;
        cout << "The string was deleted manually by calling \'delete[]\'." << endl;
    }

    cout << endl;

    {   //This is not a dummy example, this is a useful technique!
        //We use a class factory to get a CMyClass object pointer.
        //After leaving the scope the CMyClass object will be
        //destroyed automatically inside TAutoPtr<> destructor.

        TMyClassAutoPtr autoMyClass;

        if( CMyClass::GetInstancePtr( autoMyClass.ByRef() ) )
        {
            autoMyClass->SomeMethod();
        }
    }

    cout << endl;

	return 0;
}

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