⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 smartptr.h

📁 C++垃圾回收框架
💻 H
📖 第 1 页 / 共 2 页
字号:

#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 + -