//+------------------------------------------------------------------------- // // Microsoft Windows // // Copyright (C) Microsoft Corporation, 1999 - 1999 // // File: autoptr.h // //-------------------------------------------------------------------------- #ifndef AUTOPTR_H_INCLUDED #define AUTOPTR_H_INCLUDED #ifndef ASSERT #ifndef _INC_CRTDBG #include #endif // _INC_CRTDBG #define ASSERT(x) _ASSERT(x) #endif // ASSERT #include "cpputil.h" /*+-------------------------------------------------------------------------* * CAutoResourceManagementBase * * This is a base class that implements common functionality for the class * of smart resource handlers which release resource when it's destroyed. All * classes based on this class will behave identically, except the manner * in which they release their resources. * * DeleterClass is typically the class that derives from CAutoResourceManagementBase, * and must implement * * static void _Delete(ResourceType h); * * See CAutoPtr below for an example. *--------------------------------------------------------------------------*/ template class CAutoResourceManagementBase { typedef CAutoResourceManagementBase ThisClass; typedef ThisClass Releaser; DECLARE_NOT_COPIABLE (ThisClass) DECLARE_NOT_ASSIGNABLE (ThisClass) // protected ctor so only derived classes can intantiate protected: explicit CAutoResourceManagementBase(ResourceType h = 0) throw() : m_hResource(h) {} public: ~CAutoResourceManagementBase() throw() { Delete(); } void Attach(ResourceType p) throw() { ASSERT(m_hResource == NULL); m_hResource = p; } ResourceType Detach() throw() { ResourceType const p = m_hResource; m_hResource = NULL; return p; } /* * Returns the address of the pointer contained in this class. * This is useful when using the COM/OLE interfaces to create * allocate the object that this class manages. */ ResourceType* operator&() throw() { /* * This object must be empty now, or the data pointed to will be leaked. */ ASSERT (m_hResource == NULL); return &m_hResource; } operator ResourceType() const throw() { return m_hResource; } bool operator==(int p) const throw() { ASSERT(p == NULL); return m_hResource == NULL; } bool operator!=(int p) const throw() { ASSERT(p == NULL); return m_hResource != NULL; } bool operator!() const throw() { return m_hResource == NULL; } void Delete() throw() { if (m_hResource != NULL) { DeleterClass::_Delete (m_hResource); m_hResource = NULL; } } private: ResourceType m_hResource; }; // class CAutoResourceManagementBase /*+-------------------------------------------------------------------------* * CAutoPtrBase * * This is a base class that implements common functionality for the class * of smart pointers which delete its pointee when it's destroyed. All * classes based on this class will behave identically, except the manner * in which they destroy their pointees. * * DeleterClass is typically the class that derives from CAutoPtrBase, and * must implement * * static void _Delete(T* p); * * This template reuses CAutoResourceManagementBase to manage the pointer * * See CAutoPtr below for an example. *--------------------------------------------------------------------------*/ template class CAutoPtrBase : public CAutoResourceManagementBase { typedef CAutoPtrBase ThisClass; typedef CAutoResourceManagementBase BaseClass; typedef BaseClass Releaser; DECLARE_NOT_COPIABLE (ThisClass) DECLARE_NOT_ASSIGNABLE (ThisClass) // protected ctor so only derived classes can intantiate protected: explicit CAutoPtrBase(T* p = 0) throw() : BaseClass(p) {} public: T& operator*() const throw() { T* ptr = *this; // use operator defined by the BaseClass for conversion ASSERT(ptr != NULL); return *ptr; } T* operator->() const throw() { T* ptr = *this; // use operator defined by the BaseClass for conversion ASSERT(ptr != NULL); return ptr; } }; // class CAutoPtrBase /*+-------------------------------------------------------------------------* * CAutoPtr * * CAutoPtrBase-based class that deletes pointers allocated with * operator new. *--------------------------------------------------------------------------*/ template class CAutoPtr : public CAutoPtrBase > { typedef CAutoPtrBase > BaseClass; friend BaseClass::Releaser; public: explicit CAutoPtr(T* p = 0) throw() : BaseClass(p) {} private: // only CAutoPtrBase should call this static void _Delete (T* p) { delete p; } }; /*+-------------------------------------------------------------------------* * CAutoArrayPtr * * CAutoPtrBase-based class that deletes pointers allocated with * operator new[]. *--------------------------------------------------------------------------*/ template class CAutoArrayPtr : public CAutoPtrBase > { typedef CAutoPtrBase > BaseClass; friend BaseClass::Releaser; public: explicit CAutoArrayPtr(T* p = 0) throw() : BaseClass(p) {} private: // only CAutoPtrBase should call this static void _Delete (T* p) { delete[] p; } }; /*+-------------------------------------------------------------------------* * CCoTaskMemPtr * * CAutoPtrBase-based class that deletes pointers allocated with * CoTaskMemAlloc. *--------------------------------------------------------------------------*/ template class CCoTaskMemPtr : public CAutoPtrBase > { typedef CAutoPtrBase > BaseClass; friend BaseClass::Releaser; public: explicit CCoTaskMemPtr(T* p = 0) throw() : BaseClass(p) {} private: // only CAutoPtrBase should call this static void _Delete (T* p) { if (p != NULL) CoTaskMemFree (p); } }; /*+-------------------------------------------------------------------------* * CAutoGlobalPtr * * CAutoPtrBase-based class that deletes pointers allocated with GlobalAlloc. *--------------------------------------------------------------------------*/ template class CAutoGlobalPtr : public CAutoPtrBase > { typedef CAutoPtrBase > BaseClass; friend BaseClass::Releaser; public: explicit CAutoGlobalPtr(T* p = 0) throw() : BaseClass(p) {} private: // only CAutoPtrBase should call this static void _Delete (T* p) { if (p != NULL) GlobalFree (p); } }; /*+-------------------------------------------------------------------------* * CAutoLocalPtr * * CAutoPtrBase-based class that deletes pointers allocated with LocalAlloc. *--------------------------------------------------------------------------*/ template class CAutoLocalPtr : public CAutoPtrBase > { typedef CAutoPtrBase > BaseClass; friend BaseClass::Releaser; public: explicit CAutoLocalPtr(T* p = 0) throw() : BaseClass(p) {} private: // only CAutoPtrBase should call this static void _Delete (T* p) { if (p != NULL) LocalFree (p); } }; /*+-------------------------------------------------------------------------* * CHeapAllocMemPtr * * CAutoPtrBase-based class that deletes pointers allocated from the process * default heap with HeapAlloc. *--------------------------------------------------------------------------*/ template class CHeapAllocMemPtr : public CAutoPtrBase > { typedef CAutoPtrBase > BaseClass; friend BaseClass::Releaser; public: explicit CHeapAllocMemPtr(T* p = 0) throw() : BaseClass(p) {} private: // only CAutoPtrBase should call this static void _Delete (T* p) { if (p != NULL) HeapFree(::GetProcessHeap(), 0, p); } }; /*+-------------------------------------------------------------------------* * CAutoWin32Handle * * CAutoPtrBase-based class that closes HANDLE on destruction *--------------------------------------------------------------------------*/ class CAutoWin32Handle : public CAutoResourceManagementBase { typedef CAutoResourceManagementBase BaseClass; friend BaseClass::Releaser; public: explicit CAutoWin32Handle(HANDLE p = NULL) throw() : BaseClass(p) {} bool IsValid() { return IsValid(*this); // use base class operator to convet to HANDLE } private: static bool IsValid (HANDLE p) { return (p != NULL && p != INVALID_HANDLE_VALUE); } // only CAutoResourceManagementBase should call this static void _Delete (HANDLE p) { if (IsValid(p)) CloseHandle(p); } }; /*+-------------------------------------------------------------------------* * CAutoAssignOnExit * * instances of this template class assign the value in destructor. * * USAGE: Say you have variable "int g_status" which must be set to S_OK before * you leave the function. To do so declare following in the function: * * CAutoAssignOnExit any_object_name(g_status); *--------------------------------------------------------------------------*/ template class CAutoAssignOnExit { T& m_rVariable; // variable, which needs to be modified in destructor public: // constructor CAutoAssignOnExit( T& rVariable ) : m_rVariable(rVariable) {} // destructor ~CAutoAssignOnExit() { // assign designated final value m_rVariable = value; } }; #endif // AUTOPTR_H_INCLUDED