//////////////////////////////////////////////////////////////////////////////// // // Filename : AutoPtr.h // Purpose : To supply auto pointers of different kinds. // CAutoPointer Generic pointer needs a deletor // class to instaciate. // CAutoMallocPonter A malloc allocated pointer. // CAutoClassPointer A "new" allocated pointer // CAutoArrayPointer A "new[]" allocated pointer // CAutoOlePointer A pointer that should be // "Release()". // // Project : PersistentQuery // Component: Common // // Author : urib // // Log: // // Jan 15 1997 urib Creation // Jan 19 1997 urib Fix Ole pointer. Enable instanciation without // ownership // Jun 9 1997 urib Better OlePointer. Some safety fixes. // Nov 17 1997 urib Add ole task pointer. // Jun 30 1998 dovh Add Assert to CAutoPointer operator= // Feb 25 1999 urib Add smart pointer typedef macro. // Jun 23 1999 urib Add equality op. // Aug 5 1999 urib Fix a memory leak bug in the assignment operator // of CAutoPointer. Add assignment operation // creation macro. // Dec 1 1999 urib Change return type from int to bool in IsValid. // //////////////////////////////////////////////////////////////////////////////// #ifndef AUTOPTR_H #define AUTOPTR_H #include "tracer.h" #include #pragma once //////////////////////////////////////////////////////////////////////////////// // // return type for 'identifier::operator ->'is not a UDT or reference to a UDT. // Will produce errors if applied using infix notation // //////////////////////////////////////////////////////////////////////////////// #pragma warning(disable: 4284 4786) template class CAutoPointer { protected: typedef Deletor m_Deletor; public: typedef T m_PointerType; // Constructors CAutoPointer(T* pt = NULL, BOOL fOwnMemory = TRUE) :m_fIOwnTheMemory(fOwnMemory && (pt != NULL)) ,m_ptThePointer(pt) {} CAutoPointer(const CAutoPointer& acp) { m_fIOwnTheMemory = acp.m_fIOwnTheMemory; m_ptThePointer = acp.Detach(); } // Assignemnt operation. CAutoPointer& operator=(const CAutoPointer& acp) { if (m_ptThePointer != acp.m_ptThePointer) { if (m_fIOwnTheMemory) Deletor::DeleteOperation(m_ptThePointer); m_fIOwnTheMemory = acp.m_fIOwnTheMemory; m_ptThePointer = acp.Detach(); } else { Assert( (!m_fIOwnTheMemory) || acp.m_fIOwnTheMemory ); // Note: R.H.S "inherits" memory oenership from L.H.S., // and L.H.S. ownership is cancelled by Detach! bool ftmp = acp.m_fIOwnTheMemory; acp.Detach(); m_fIOwnTheMemory = ftmp; } return (*this); } CAutoPointer& operator=(int null) { Assert(null == 0); return operator=(reinterpret_cast(NULL)); } bool operator==(const CAutoPointer& acp) { return m_ptThePointer == acp.m_ptThePointer; } // If it is our memory delete the pointer. ~CAutoPointer() { if(m_fIOwnTheMemory) Deletor::DeleteOperation(m_ptThePointer); } // Return the pointer and mark that it is no longer our memory. T* Detach() const { // This is to escape the const restriction. We don't change the pointer // but we still do the marking. ((CAutoPointer*)this)->m_fIOwnTheMemory = FALSE; return (m_ptThePointer); } // Return the actual pointer if you want to use it someplace T* Get() const { return m_ptThePointer; } // Return if the pointer is valid. bool IsValid() { return !!m_ptThePointer; } // Indirection T& operator *() const { return * Get(); } // Dereference T* operator ->() const { return Get(); } protected: // The pointer to keep. T* m_ptThePointer; // Is the memory ours? bool m_fIOwnTheMemory; }; #define CONSTRUCTORS(AutoPointer) \ \ AutoPointer(m_PointerType* pt = NULL, \ BOOL fOwnMemory = TRUE) \ :CAutoPointer(pt, fOwnMemory) \ { \ } \ \ AutoPointer(const AutoPointer& aop) \ :CAutoPointer(aop) \ { \ } \ #define ASSIGNMENT_OPERATORS(AutoPointer) \ \ AutoPointer& \ operator=(const AutoPointer& acp) \ { \ CAutoPointer::operator=(acp); \ \ return *this; \ } \ \ AutoPointer& \ operator=(int null) \ { \ CAutoPointer::operator=(null); \ \ return *this; \ } //////////////////////////////////////////////////////////////////////////////// // // CAutoClassPointer class definition // //////////////////////////////////////////////////////////////////////////////// template class CClassDeletor { public: static void DeleteOperation(T* pt) { if (pt) delete pt; } }; template class CAutoClassPointer : public CAutoPointer > { public: CONSTRUCTORS(CAutoClassPointer); ASSIGNMENT_OPERATORS(CAutoClassPointer); }; //////////////////////////////////////////////////////////////////////////////// // // CAutoOlePointer class definition // //////////////////////////////////////////////////////////////////////////////// template class COleDeletor { public: static void DeleteOperation(T* pt) { if (pt) pt->Release(); } }; template class CAutoOlePointer : public CAutoPointer > { public: CONSTRUCTORS(CAutoOlePointer); ASSIGNMENT_OPERATORS(CAutoOlePointer); public: T** operator &() { m_fIOwnTheMemory = TRUE; return &m_ptThePointer; } }; //////////////////////////////////////////////////////////////////////////////// // // CAutoTaskPointer class definition // //////////////////////////////////////////////////////////////////////////////// template class CTaskDeletor { public: static void DeleteOperation(T* pt) { if (pt) CoTaskMemFree(pt); } }; template class CAutoTaskPointer : public CAutoPointer > { public: CONSTRUCTORS(CAutoTaskPointer); ASSIGNMENT_OPERATORS(CAutoTaskPointer); public: T** operator &() { m_fIOwnTheMemory = TRUE; return &m_ptThePointer; } }; //////////////////////////////////////////////////////////////////////////////// // // CAutoMallocPointer class definition // //////////////////////////////////////////////////////////////////////////////// template class CMallocDeletor { public: static void DeleteOperation(T* pt) { if (pt) free(pt); } }; template class CAutoMallocPointer : public CAutoPointer > { public: CONSTRUCTORS(CAutoMallocPointer); ASSIGNMENT_OPERATORS(CAutoMallocPointer); public: T& operator[](size_t n) { return *(Get() + n); } }; //////////////////////////////////////////////////////////////////////////////// // // CAutoArrayPointer class definition // //////////////////////////////////////////////////////////////////////////////// template class CArrayDeletor { public: static void DeleteOperation(T* pt) { if (pt) delete[] pt; } }; template class CAutoArrayPointer : public CAutoPointer > { public: CONSTRUCTORS(CAutoArrayPointer); ASSIGNMENT_OPERATORS(CAutoArrayPointer); public: T& operator[](size_t n) { return *(Get() + n); } }; // // Simple macro to define the standard COM pointer. // #define PQ_COM_SMARTPTR_TYPEDEF(Interface) \ _COM_SMARTPTR_TYPEDEF(Interface, IID_##Interface) #endif /* AUTOPTR_H */