After some looking into the matter I’ve decided
that either there is no way to do this using
the standard Symbian API or I that I am too
blind to find one, I wrote one myself.
The point is to make a dynamic array’s ResetAndDestroy() method being called
for an array pushed onto the cleanup stack upon
a leave or an explicit call to PopAndDestroy().
While this functionality might be rarely necessary or desired, there are cases where
allocating an dynamic array on the heap is
the most elegant solution. This approach
requires efficient and clean cleanup support,
and here’s how I’ve addressed the problem.
In practice, here’s how it’s used (code simplified and lacking error checking etc.):
SomeCode.cpp:
#include "CleanupResetAndDestroy.h"
..
RPointerArray<CMyType>* list = new RPointerArray<CMyType>( 1 );
CleanupResetAndDestroyPushL( list );
// add stuff to list
// use list
CleanupStack::PopAndDestroy(); // list
What happens in PopAndDestroy():
- . list->ResetAndDestroy();
- . delete list;
The following code is from my soon-to-be-released project Nova3D, written
under the LGPL licence.
CleanupResetAndDestroy.h:
/*
* $Id: CleanupResetAndDestroy.h,v 1.1 2004/10/16 11:02:37 matti Exp $
*
* Nova 3D Engine - A real-time 3D graphics framework for Symbian environments
* Copyright (C) 2001-2004 Matti Dahlbom
*
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Contact: Matti Dahlbom <matti at 777-team dot org>
*/
#ifndef __CLEANUPRESETANDDESTROY_H
#define __CLEANUPRESETANDDESTROY_H
#include <e32base.h>
template <class T> void CleanupResetAndDestroyPushL( T* aObj );
/**
* Utility template class to perform thorough cleanup for classes like
* RPointerArray; upon cleanup, ResetAndDestroy() is called for the object
* after which the object itself is deleted.
*
* @author Matti Dahlbom
* @version $Name: $, $Revision: 1.1 $
*/
template <class T> class TCleanupResetAndDestroy : public CBase
{
private: // Constructors and desctructor
inline TCleanupResetAndDestroy( T* aObj );
inline ~TCleanupResetAndDestroy();
private: // Data
T* iObj;
#ifdef __WINS__
// MSVC++ way
friend void CleanupResetAndDestroyPushL( T* aObj );
#else
// gcc way
friend void CleanupResetAndDestroyPushL<>( T* aObj );
#endif
};
//=================================================
// template class method implementations
//=================================================
template <class T> TCleanupResetAndDestroy<T>::TCleanupResetAndDestroy( T* aObj )
: iObj( aObj )
{
}
template <class T> TCleanupResetAndDestroy<T>::~TCleanupResetAndDestroy()
{
iObj->ResetAndDestroy();
delete iObj;
}
/**
* Pushes an object on cleanup stack. Object's ResetAndDestroy() will be called
* upon cleanup.
*/
template <class T> inline void CleanupResetAndDestroyPushL( T* aObj )
{
TCleanupResetAndDestroy<T>* item = new (ELeave) TCleanupResetAndDestroy<T>( aObj );
CleanupStack::PushL( item );
}
#endif
|