|
//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.