/* libzz
*
* This program is distributed under the GNU General Public License, version 2.
* A copy of this license is included with this source.
*
* Copyright 2000-2006, Toni Thomsson <toni@tonjac.org>
*/
#ifndef zz_handle_h
#define zz_handle_h
#include <zz_use_counter.h>
/**
Template class used to keep track of objects allocated
on the heap. Frees the wrapped object when handle goes
out of scope. This class can't create objects allocated
on the heap.
@author Toni Thomsson, toni@tonjac.org
*/
template< class T > class CzzHandle
{
public:
/**
Create a handle to a object allocated on the heap.
Sample:
<pre>
CzzHandle<CxxObject> handle( new CxxObject[ 10 ], true );
CzzHandle<CxxFoo> foo = new CxxFoo( 1, "kalle" );
CzzHandle<CxxObject> tmp;
tmp = handle;
tmp->callMethod( foo );
doSomething( tmp );
// No need to free objects, they are freed when the
// handle goes out of scope
</pre>
@param obj Object
@param vector Array
*/
CzzHandle( T* obj, bool vector )
: m_Object( obj ), m_Counter( new CzzUseCounter() ),
m_Vector( vector )
{
m_Counter->addRef();
};
/**
Create a empty handle
*/
CzzHandle( void )
: m_Object( 0 ), m_Counter( 0 ), m_Vector( false )
{
};
/**
Copy constructor
*/
CzzHandle( const CzzHandle& handle )
: m_Object( handle.m_Object ), m_Counter( handle.m_Counter ),
m_Vector( handle.m_Vector )
{
m_Counter->addRef();
};
/**
Copy constructor
*/
CzzHandle( T* handle )
: m_Object( handle ), m_Counter( new CzzUseCounter() ),
m_Vector( false )
{
m_Counter->addRef();
};
virtual ~CzzHandle()
{
if( m_Counter && m_Counter->release() == 0 )
{
if( m_Vector )
delete [] m_Object;
else
delete m_Object;
delete m_Counter;
}
};
/** Object */
T* operator->()
{
return m_Object;
};
/** Object */
operator T*( void )
{
return m_Object;
};
/** Object */
T* object( void )
{
return m_Object;
};
/** Value of object pointer */
T value( void )
{
return *m_Object;
};
/** Reference */
T& ref( void )
{
return *m_Object;
};
/** Assignment */
const CzzHandle& operator=( const CzzHandle& handle )
{
m_Object = handle.m_Object;
m_Counter = handle.m_Counter;
m_Vector = handle.m_Vector;
m_Counter->addRef();
return *this;
};
protected:
/** Usage counter */
CzzUseCounter* m_Counter;
/** Wrapped object */
T* m_Object;
/** Array? */
bool m_Vector;
private:
/** Not allowed to allocate on the heap */
void* operator new( size_t n ) { return 0; };
void* operator new[]( size_t n ) { return 0; };
void operator delete( void*, size_t n ) { };
void operator delete[]( void*, size_t n ) { };
};
#endif // zz_handle_h