// auto_ptr_test.cpp
//
// Copyright (c) 2002 mBrain SOftware.
//
// Test programn for auto_ptr template
#include <e32base.h>
#include <e32cons.h>
#include <auto_ptr.h>
_LIT(Kauto_ptr_test, "auto_ptr_test");
// forward reference
static void mainL();
static CConsoleBase* gConsole; // write all your messages to this
static void _init()
{
_LIT(KFailed,"failed: leave code=%d");
_LIT(KOK,"ok");
// create the console
gConsole = Console::NewL(Kauto_ptr_test, TSize(KConsFullScreen, KConsFullScreen));
CleanupStack::PushL(gConsole);
TRAPD(error, mainL()); // perform example function
if (error)
gConsole->Printf(KFailed, error);
else
gConsole->Printf(KOK);
CleanupStack::PopAndDestroy(); // gConsole
}
// main function called by E32
GLDEF_C TInt E32Main()
{
__UHEAP_MARK;
// create the cleanup stack
CTrapCleanup* cleanup = CTrapCleanup::New();
TRAPD(error, _init());
__ASSERT_ALWAYS(!error, User::Panic(Kauto_ptr_test, error));
delete cleanup;
__UHEAP_MARKEND;
return 0; // and return
}
//------------------------------------------------------------
//
// The example code starts here
//
//------------------------------------------------------------
_LIT(KCClassConstructor, " CClass::CClass() <aWhich>=%d\n");
_LIT(KCClassConstructL, " CClass::ConstructL() <iWhich>=%d\n");
_LIT(KCClassPrint, " CClass::Print() <iWhich>=%d\n");
_LIT(KCClassDestructor, " CClass::~CClass() <iWhich>=%d\n");
class CClass: public CBase
{
public:
CClass(TInt aWhich);
void ConstructL();
static auto_ptr<CClass> NewLC(TInt aWhich = 0);
static CClass* NewL(TInt aWhich = 0);
~CClass();
void Print() const;
// members
TInt iWhich; // differentiate objects
CClass* iMember;
};
CClass::CClass(TInt aWhich): iWhich(aWhich)
{
gConsole->Printf(KCClassConstructor, iWhich);
}
void CClass::ConstructL()
{
gConsole->Printf(KCClassConstructL, iWhich);
}
auto_ptr<CClass> CClass::NewLC(TInt aWhich)
{
auto_ptr<CClass> self(new(ELeave) CClass(aWhich));
self->ConstructL();
return self;
}
CClass* CClass::NewL(TInt aWhich)
{
auto_ptr<CClass> self(new(ELeave) CClass(aWhich));
self->ConstructL();
return self.release();
}
CClass::~CClass()
{
delete iMember;
gConsole->Printf(KCClassDestructor, iWhich);
}
void CClass::Print() const
{
gConsole->Printf(KCClassPrint, iWhich);
}
//----------------------------------------------------
//
//
//
//-----------------------------------------------------
static TInt DoSomeWorkL(CClass* aPtr)
{
_LIT(KDoSomeWorkEnter, "DoSomeWorkL() enter\n");
gConsole->Printf(KDoSomeWorkEnter);
// use the debugger to change the return value
TInt result = KErrNone;
aPtr->Print();
_LIT(KDoSomeWorkExit, "DoSomeWorkL() exit\n");
gConsole->Printf(KDoSomeWorkExit);
return result;
}
static void DoSomeMoreWorkL(CClass* aPtr)
{
_LIT(KDoSomeMoreWorkEnter, "DoSomeMoreWorkL() enter\n");
gConsole->Printf(KDoSomeMoreWorkEnter);
aPtr->Print();
_LIT(KDoSomeMoreWorkExit, "DoSomeMoreWorkL() exit\n");
gConsole->Printf(KDoSomeMoreWorkExit);
}
static void Example1L();
static void Example2L();
static void Example3L();
static void Example4L();
static void Example5L();
static void Example6L();
static void Example7L();
static void Test();
void mainL()
{
_LIT(KEnterANumber, "Enter a number to run the example [1..7], enter T to run tests\n");
gConsole->Printf(KEnterANumber);
TInt ch = gConsole->Getch();
switch (ch)
{
case '0': return;
case '1': Example1L(); break;
case '2': Example2L(); /* will crash */ break;
case '3': Example3L(); break;
case '4': Example4L(); break;
case '5': Example5L(); break;
case '6': Example6L(); break;
case '7': Example7L(); break;
case 't':
case 'T': Test();
default: break;
}
// wait for a keypress
_LIT(KPressAnyKey,"\n[press any key]");
gConsole->Printf(KPressAnyKey);
gConsole->Getch();
}
void Example1L()
{
_LIT(KExample, "\nExample 1\n\n");
gConsole->Printf(KExample);
CClass* localPtr = CClass::NewL();
CleanupStack::PushL(localPtr);
(void) DoSomeWorkL(localPtr);
CleanupStack::PopAndDestroy(); // localPtr
}
void Example2L()
{
_LIT(KExample, "\nExample 2, will panic\n\n");
gConsole->Printf(KExample);
CClass* localPtr = CClass::NewL();
CleanupStack::PushL(localPtr);
TInt res = DoSomeWorkL(localPtr);
if (KErrNone == res)
return; // oops, localPtr is still on the cleanup stack
DoSomeMoreWorkL(localPtr);
CleanupStack::PopAndDestroy(); // localPtr
}
void Example3L()
{
_LIT(KExample, "\nExample 3, multiple CleanupStack::Pop()s\n\n");
gConsole->Printf(KExample);
CClass* localPtr = CClass::NewL();
CleanupStack::PushL(localPtr);
TInt res = DoSomeWorkL(localPtr);
if (KErrNone == res)
{
CleanupStack::PopAndDestroy(); // localPtr
return;
}
DoSomeMoreWorkL(localPtr);
CleanupStack::PopAndDestroy(); // localPtr
}
void Example4L()
{
_LIT(KExample, "\nExample 4, auto_ptr\n\n");
gConsole->Printf(KExample);
auto_ptr<CClass> localPtr(CClass::NewL());
int res = DoSomeWorkL(localPtr.get());
if (KErrNone == res)
return; // automatic destruction of *localPtr
DoSomeMoreWorkL(localPtr.get());
// automatic destruction of *localPtr
}
void Example5L()
{
_LIT(KExample, "\nExample 5, ownership to member var\n\n");
gConsole->Printf(KExample);
auto_ptr<CClass> p1(CClass::NewL(1));
auto_ptr<CClass> p2(CClass::NewL(2));
// transfer ownership
p2->iMember = p1.release();
DoSomeMoreWorkL(p2.get());
}
void Example6L()
{
_LIT(KExample, "\nExample 6, copy constructor\n\n");
gConsole->Printf(KExample);
auto_ptr<CClass> p1(CClass::NewL(1));
// copy constructor transfers ownership
auto_ptr<CClass> p2(p1);
if (p1.get() != 0)
p1->Print();
if (p2.get() != 0)
p2->Print();
// copy constructor transfers ownership
auto_ptr<CClass> p3(CClass::NewLC(3));
p3->Print();
}
void Example7L()
{
_LIT(KExample, "\nExample 7, assignment operator\n\n");
gConsole->Printf(KExample);
auto_ptr<CClass> p1(CClass::NewL());
// assignment operator transfers ownership
auto_ptr<CClass> p2 = p1;
if (p1.get() != 0)
p1->Print();
if (p2.get() != 0)
p2->Print();
// assignment operator transfers ownership
auto_ptr<CClass> p3 = CClass::NewLC(3);
p3->Print();
}
void Test()
{
for (;;)
{
_LIT(KEnterANumber, "\nEnter a number to test the example for memory leaks [1..7], 0 to stop\n");
gConsole->Printf(KEnterANumber);
TInt ch = gConsole->Getch();
if (ch == '0')
return;
_LIT(KExample, "\n\n----- Example %d -----\n\n");
gConsole->Printf(KExample, (ch - '0'));
TInt error;
// run example 5 under a trap harness
__UHEAP_MARK;
for (TInt i= 0; ; i++)
{
_LIT(KRun, "\n--- %d allocations -----\n");
gConsole->Printf(KRun, i);
error = KErrNone;
__UHEAP_FAILNEXT(i);
__UHEAP_MARK;
switch (ch)
{
case '1': TRAP(error, Example1L()); break;
case '2': TRAP(error, Example2L()); /* will crash */ break;
case '3': TRAP(error, Example3L()); break;
case '4': TRAP(error, Example4L()); break;
case '5': TRAP(error, Example5L()); break;
case '6': TRAP(error, Example6L()); break;
case '7': TRAP(error, Example7L()); break;
default: break;
}
__UHEAP_MARKEND;
if (error != KErrNoMemory)
break;
_LIT(KPressAnyKey,"\n[press any key]\n");
gConsole->Printf(KPressAnyKey);
gConsole->Getch();
}
__UHEAP_MARKEND;
__UHEAP_RESET;
if (error == KErrNone)
{
_LIT(KLeaveOk,"\nNo leaks\n");
gConsole->Printf(KLeaveOk);
}
}
}
评论0