windows-nt/Source/XPSP1/NT/admin/activec/inc/autoptr.h
2020-09-26 16:20:57 +08:00

386 lines
10 KiB
C++

//+-------------------------------------------------------------------------
//
// 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 <crtdbg.h>
#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<typename ResourceType, typename DeleterClass>
class CAutoResourceManagementBase
{
typedef CAutoResourceManagementBase<ResourceType, DeleterClass> 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<typename T, typename DeleterClass>
class CAutoPtrBase : public CAutoResourceManagementBase<T*, DeleterClass>
{
typedef CAutoPtrBase<T, DeleterClass> ThisClass;
typedef CAutoResourceManagementBase<T*, DeleterClass> 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 T>
class CAutoPtr : public CAutoPtrBase<T, CAutoPtr<T> >
{
typedef CAutoPtrBase<T, CAutoPtr<T> > 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 T>
class CAutoArrayPtr : public CAutoPtrBase<T, CAutoArrayPtr<T> >
{
typedef CAutoPtrBase<T, CAutoArrayPtr<T> > 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 T>
class CCoTaskMemPtr : public CAutoPtrBase<T, CCoTaskMemPtr<T> >
{
typedef CAutoPtrBase<T, CCoTaskMemPtr<T> > 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 T>
class CAutoGlobalPtr : public CAutoPtrBase<T, CAutoGlobalPtr<T> >
{
typedef CAutoPtrBase<T, CAutoGlobalPtr<T> > 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 T>
class CAutoLocalPtr : public CAutoPtrBase<T, CAutoLocalPtr<T> >
{
typedef CAutoPtrBase<T, CAutoLocalPtr<T> > 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 T>
class CHeapAllocMemPtr : public CAutoPtrBase<T, CHeapAllocMemPtr<T> >
{
typedef CAutoPtrBase<T, CHeapAllocMemPtr<T> > 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<HANDLE, CAutoWin32Handle>
{
typedef CAutoResourceManagementBase<HANDLE, CAutoWin32Handle> 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<int,S_OK> any_object_name(g_status);
*--------------------------------------------------------------------------*/
template<typename T, T value>
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