[Gdal-dev] OGR Spatial Reference smart pointer class

Chapman, Martin MChapman at sanz.com
Fri Aug 27 02:50:10 EDT 2004


Frank,
 
Inspired by ATL's CComPtr and memory.h's auto_ptr class I decided to write a quick smart pointer class for the OGRSpatialReference class to ensure that I was always calling Reference() and Dereference() correctly, even if an error occurs.  The attached header file (OGRPtr.h) contains a template class called OGRPtr.  The class is a smart pointer wrapper for the OGRSpatialReference class.  It overloads the appropriate pointer operators so you can use the class just like a pointer to spatial refs allocated on the heap.  Because the template class is allocated on the stack, the smart pointers destructor will always get called when it goes out of scope.  In the destructor I call Dereference() on the encapsulated pointer, thus ensuring correct memory deallocation even in the event of an error.  This works much like memory.h's auto_ptr class, which calls delete instead.  The overhead is small for the no-leak guarantee for server systems that need to run for months on end.  Here is some code snippets on how to use it:
 
#include "OGRPtr.h"
 
// does not call reference but could if you un comment the code in the destructor of OGRPtr to do so
COGRPtr< OGRSpatialReference> spSRS = new OGRSpatialReference(GetWellKnownText());
 
// then use pointer as normal
spSRS->SetProjCS("UTM 17 / WGS84");

//if you want you can return the raw pointer without calling dereference,
//otherwise Dereference always gets called when the COGRPtr class goes out of scope
return spSRS.Detach();
...
 
//there are also several other useful function and overloaded operators...
!, <, ==, *, &, ->, =, Attach(), Detach(), CopyTo(), etc...
 
 
Anyway, I thought you might want to include it as a util class or something for OGRSpatialReference because of the ref counting.  It could be expanded to work with other classes if they also use reference counting and derive from a common base class.  If not, hopefully someone will find it useful.
 
Best Reguards,
Martin Chapman
 
 
-------------- next part --------------
#ifndef OGRPtr_h
  #define OGRPtr_h

#include "gdal_priv.h"

#define OGR_OK (0x00000000L)
#define OGR_POINTER (0x00000001L)

template <class T>
class RefDeref : public T
{
public:
	long Reference();
	long Dereference();
};

template <class T>
class COGRPtrObject
{
public:
	typedef T OGRPtrClass;
	~COGRPtrObject() throw() {if (p) p->Dereference();}
	bool operator ! () const throw() {return (p == NULL);}
	bool operator < (T* pT) const throw() { return p < pT;}
	bool operator == (T* pT) const throw() {return p == pT;}
	operator T * () const throw() {return p;}
	T& operator * () const throw()
	{
		assert(p != NULL);
		return *p;
	}
	T** operator & () throw()
	{
		assert(p == NULL);
		return &p;
	}
	RefDeref<T>* operator -> () const throw()
	{
		assert(p != NULL);
		return (RefDeref<T>*)p;
	}
	void Dereference() throw()
	{
		T* pTemp = p;
		if (pTemp)
		{
			p = NULL;
			pTemp->Dereference();
		}
	}
	void Attach(T* p2) throw()
	{
		if (p) p->Dereference();
		p = p2;
	}
	T* Detach() throw()
	{
		T* pt = p;
		p = NULL;
		return pt;
	}
	long CopyTo(T** ppT) throw()
	{
		assert(ppT != NULL);
		if (ppT == NULL) return OGR_POINTER;
		*ppT = p;
		if (p) p->Reference();
		return OGR_OK;
	}
	T* p;

protected:
	COGRPtrObject() throw() {p = NULL;}
	COGRPtrObject(int nNull) throw()
	{
		assert(nNull == 0);
		(void) nNull;
		p = NULL;
	}
	COGRPtrObject(T* lp) throw()
	{
		p = lp;
		//if (p != NULL) p->Reference();
	}
};

template <class T>
class COGRPtr : public COGRPtrObject<T>
{
public:
	COGRPtr() throw() {}
	COGRPtr(int nNull) throw() : COGRPtrObject<T>(nNull) {}
	COGRPtr(T* lp) throw() : COGRPtrObject<T>(lp) {}
	COGRPtr(const COGRPtr<T>& lp) throw() : COGRPtrObject<T>(lp.p) {}
	T* operator = (T* lp) throw() {return static_cast<T*>(OGRPtrAssign((OGRSpatialReference**)&p, lp));}
	template <typename I>
	T* operator = (const COGRPtr<I>& lp) throw()
	{return static_cast<T*>(OGRPtrAssign((OGRSpatialReference**)&p, lp));}
	template <>
	T* operator = (const COGRPtr<T>& lp) throw() : COGRPtrBase<T>(lp)
	{return static_cast<T*>(OGRPtrAssign((OGRSpatialReference**)&p, lp));}
	OGRSpatialReference* OGRPtrAssign(OGRSpatialReference** pp, OGRSpatialReference* lp)
	{
		if (pp == NULL) return NULL;	
		if (lp != NULL) lp->Reference();
		if (*pp) (*pp)->Dereference();
		*pp = lp;
		return lp;
	}
};

#endif


More information about the Gdal-dev mailing list