?? smartptr.h
字號:
#ifndef _SMARTPTR_H_
#define _SMARTPTR_H_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
/*************************************************************************
FILE : SmartPtr.h
Date : 20 December 1998
Author : Stefan Tchekanov (stefant@iname.com)
Description: The template class SmartPtr performs Reference Counting
Garbage Collection and/or Object Level Thread Synchronization.
Classes : SmartPtr - The SmartPtr class
RefCountPtr - Reference Counting Garbage Collection
SyncPtr - Synchronized access without Reference Counting Garbage Collection
SyncRefCountPtr - Synchronized access with Reference Counting Garbage Collection
SmartPtrBase - The base of all above classes. Used as a common base so
an assignment between different pointers is able.
For examples how to use these classes look at the end
of this file.
Implementation classes that SHOULD NEVER be used directly.
CRefCountRep
CSyncAccessRep
CSyncRefCountRep
CSyncAccess
Copyright notice:
Written by Stefan Tchekanov (stefant@iname.com)
Copyright(c) 1998,1999,2000
This code may be used in compiled form in any way you desire. This
file may be redistributed unmodified by any means PROVIDING it is
not sold for profit without the authors written consent, and
providing that this notice and the authors name is included. If
the source code in this file is used in any commercial application
then a simple email would be nice.
This file is provided "as is" with no expressed or implied warranty.
The author accepts no liability if it causes any damage to your
computer.
*************************************************************************/
/* # Revisions # */
/*************************************************************************
REVISION ON 7.January.2000 14:31:34 By Stefan Tchekanov
Comments : SmartPtr objects can point to objects of other types
not only to objects of their type.
*************************************************************************/
/*************************************************************************
REVISION ON 09 April 1999 11:24:38 By Stefan Tchekanov
Comments : SmartPtr objects now have size of a real pointer, Which
means that passing a SmartPtr as a function parameter is
as efficient as passing an int or a pointer.
*************************************************************************/
/////////////////////////////////////////////////////////////////////////////
// If you wrap a non-class with the SmartPtr class, you will receive
// this warning. i.e. int, short, etc...
// It is a warning you may ignore.
#pragma warning( disable : 4284 )
//
// This warning is generated when compiling in debug mode.
// Debug symbols cannot be longer than 255 but when using templates
// it is usual to have debug symbols longer tahn 255.
// You may ignore this warning.
#pragma warning( disable : 4786 )
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
// Representation class just for reference counting
/////////////////////////////////////////////////////////////////////////////
template<class T>
class CRefCountRep {
// Constructors and destructor
public:
CRefCountRep( const T* ptr );
~CRefCountRep();
// Operations
public:
long incrRefCount();
long decrRefCount();
T* getPointer() const;
T* getRealPointer() const;
bool isNull() const;
// Implementation
private:
T* m_pRealPtr;
long m_counter;
};
/////////////////////////////////////////////////////////////////////////////
template<class T>
CRefCountRep<T>::CRefCountRep( const T* ptr )
: m_pRealPtr( (T*)ptr ), m_counter( 0 ) {
}
template<class T>
CRefCountRep<T>::~CRefCountRep() {
ASSERT( m_counter <= 0 );
delete m_pRealPtr;
}
template<class T>
long CRefCountRep<T>::incrRefCount() {
return ::InterlockedIncrement( &m_counter );
}
template<class T>
long CRefCountRep<T>::decrRefCount() {
return ::InterlockedDecrement( &m_counter );
}
template<class T>
T* CRefCountRep<T>::getPointer() const {
return m_pRealPtr;
}
template<class T>
T* CRefCountRep<T>::getRealPointer() const {
return m_pRealPtr;
}
template<class T>
bool CRefCountRep<T>::isNull() const {
return m_pRealPtr == NULL;
}
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
template <class T> class CSyncAccess;
/////////////////////////////////////////////////////////////////////////////
// Representation class just for thread synchronization
/////////////////////////////////////////////////////////////////////////////
template<class T>
class CSyncAccessRep {
// Constructors and destructor
public:
CSyncAccessRep( const T* ptr );
~CSyncAccessRep();
typedef CSyncAccess<T> ACCESS;
// Operations
public:
long incrRefCount();
long decrRefCount();
ACCESS getPointer() const;
T* getRealPointer() const;
bool isNull() const;
void acquireAccess();
void releaseAccess();
// Implementation
protected:
T* m_pRealPtr;
long m_counter;
CRITICAL_SECTION m_CriticalSection;
};
/////////////////////////////////////////////////////////////////////////////
template<class T>
CSyncAccessRep<T>::CSyncAccessRep( const T* ptr )
: m_pRealPtr( (T*)ptr ), m_counter( 0 ) {
::InitializeCriticalSection( &m_CriticalSection );
}
template<class T>
CSyncAccessRep<T>::~CSyncAccessRep() {
ASSERT( m_counter <= 0 );
::DeleteCriticalSection( &m_CriticalSection );
}
template<class T>
long CSyncAccessRep<T>::incrRefCount() {
return ::InterlockedIncrement( &m_counter );
}
template<class T>
long CSyncAccessRep<T>::decrRefCount() {
return ::InterlockedDecrement( &m_counter );
}
template<class T>
CSyncAccessRep<T>::ACCESS CSyncAccessRep<T>::getPointer() const {
return this; // Object of type ACCESS (CSyncAccess<T>)
// will be automatically created on the stack
}
template<class T>
T* CSyncAccessRep<T>::getRealPointer() const {
return m_pRealPtr;
}
template<class T>
bool CSyncAccessRep<T>::isNull() const {
return m_pRealPtr == NULL;
}
template<class T>
void CSyncAccessRep<T>::acquireAccess() {
::EnterCriticalSection( &m_CriticalSection );
}
template<class T>
void CSyncAccessRep<T>::releaseAccess() {
::LeaveCriticalSection( &m_CriticalSection );
}
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
// Representation class for Reference Counting AND Thread Synchronization
/////////////////////////////////////////////////////////////////////////////
template<class T>
class CSyncRefCountRep : public CSyncAccessRep<T> {
// Constructors and destructor
public:
CSyncRefCountRep( const T* ptr );
~CSyncRefCountRep();
};
/////////////////////////////////////////////////////////////////////////////
template<class T>
CSyncRefCountRep<T>::CSyncRefCountRep( const T* ptr )
: CSyncAccessRep<T>( ptr ) {
}
template<class T>
CSyncRefCountRep<T>::~CSyncRefCountRep() {
ASSERT( m_counter <= 0 );
delete m_pRealPtr; // This is the only change needed to make in
// CSyncRefCountRep<T> class to collect the garbage and
// in the same time to do Object Level Thread Synchronization
}
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
//
// The SyncAccess class. It is used as an intermediary to achieve
// Object Level Thread Synchronization
//
/////////////////////////////////////////////////////////////////////////////
template <class T>
class CSyncAccess {
// Internally used data type
private:
typedef CSyncAccessRep<T> REP;
// Constructors and destructors
public:
// Copy constructor
CSyncAccess( const CSyncAccess& that );
CSyncAccess( const REP* rep );
~CSyncAccess();
// Operators
public:
T* operator -> ();
// Implementation
private:
REP* m_rep;
bool m_acquired;
};
/////////////////////////////////////////////////////////////////////////////
template <class T>
CSyncAccess<T>::CSyncAccess( const REP* rep )
: m_rep( (REP*)rep ), m_acquired( false ) {
}
template <class T>
CSyncAccess<T>::CSyncAccess( const CSyncAccess<REP>& that )
: m_rep( that.m_rep ), m_acquired( false ) {
}
template <class T>
CSyncAccess<T>::~CSyncAccess() {
if( m_acquired ) {
m_rep->releaseAccess();
}
}
template <class T>
T* CSyncAccess<T>::operator -> () {
// This is checked by SmartPtr<T>::operator -> () too
ASSERT( (m_rep != NULL) && (! m_rep->isNull()) );
if( ! m_acquired ) {
m_rep->acquireAccess();
m_acquired = true;
}
return m_rep->getRealPointer();
}
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
// The SmartPtr class
/////////////////////////////////////////////////////////////////////////////
class SmartPtrBase {
public:
SmartPtrBase() : m_rep( NULL )
{};
void* m_rep;
};
/////////////////////////////////////////////////////////////////////////////
template<class T, class REP, class ACCESS = T*>
class SmartPtr : public SmartPtrBase {
// Constructors and destructor
public:
// Default constructor and destructor
SmartPtr();
~SmartPtr();
// Copy constructor
SmartPtr( const SmartPtr& ptr );
// Other constructors
SmartPtr( const T* ptr );
SmartPtr( const SmartPtrBase& ptr );
// Assignment Operators
public:
SmartPtr& operator = ( const SmartPtr& ptr );
SmartPtr& operator = ( const T* ptr );
SmartPtr& operator = ( const SmartPtrBase& ptr );
// Operators
public:
ACCESS operator -> ();
T& operator * ();
// Casting operator
operator T* ();
// Comparison Operators
bool operator == ( const SmartPtrBase& ptr );
bool operator == ( const T* ptr );
bool operator != ( const SmartPtrBase& ptr );
bool operator != ( const T* ptr );
// Attributes
public:
bool IsNull() const;
long GetRefCount() const;
REP* GetRepPtr() const;
// Helper methods
protected:
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -