📄 smartptr.h
字号:
void CopyFrom( const SmartPtrBase& ptr );
void CopyFrom( const T* ptr );
// Implementation
private:
void IncrRefCount();
void DecrRefCount();
};
/////////////////////////////////////////////////////////////////////////////
template<class T, class REP, class ACCESS>
SmartPtr<T,REP,ACCESS>::SmartPtr()
{
}
template<class T, class REP, class ACCESS>
SmartPtr<T,REP,ACCESS>::~SmartPtr()
{
DecrRefCount();
}
template<class T, class REP, class ACCESS>
SmartPtr<T,REP,ACCESS>::SmartPtr( const SmartPtr& ptr )
{
CopyFrom( ptr );
}
template<class T, class REP, class ACCESS>
SmartPtr<T,REP,ACCESS>::SmartPtr( const T* ptr )
{
CopyFrom( ptr );
}
template<class T, class REP, class ACCESS>
SmartPtr<T,REP,ACCESS>::SmartPtr( const SmartPtrBase& ptr )
{
CopyFrom( ptr );
}
template<class T, class REP, class ACCESS>
void SmartPtr<T,REP,ACCESS>::CopyFrom( const SmartPtrBase& ptr )
{
if( m_rep != ptr.m_rep ) {
DecrRefCount();
m_rep = ptr.m_rep;
IncrRefCount();
}
}
template<class T, class REP, class ACCESS>
void SmartPtr<T,REP,ACCESS>::CopyFrom( const T* ptr )
{
DecrRefCount();
m_rep = (ptr != NULL) ? new REP( ptr ) : NULL;
IncrRefCount();
}
template<class T, class REP, class ACCESS>
SmartPtr<T,REP,ACCESS>& SmartPtr<T,REP,ACCESS>::operator = ( const SmartPtr& ptr ) {
CopyFrom( ptr );
return *this;
}
template<class T, class REP, class ACCESS>
SmartPtr<T,REP,ACCESS>& SmartPtr<T,REP,ACCESS>::operator = ( const T* ptr ) {
CopyFrom( ptr );
return *this;
}
template<class T, class REP, class ACCESS>
SmartPtr<T,REP,ACCESS>& SmartPtr<T,REP,ACCESS>::operator = ( const SmartPtrBase& ptr ) {
CopyFrom( ptr );
return *this;
}
template<class T, class REP, class ACCESS>
ACCESS SmartPtr<T,REP,ACCESS>::operator -> () {
ASSERT( ! IsNull() );
return GetRepPtr()->getPointer();
}
template<class T, class REP, class ACCESS>
T& SmartPtr<T,REP,ACCESS>::operator * () {
ASSERT( ! IsNull() );
return *(GetRepPtr()->getRealPointer());
}
template<class T, class REP, class ACCESS>
SmartPtr<T,REP,ACCESS>::operator T* () {
return ( IsNull() ) ? NULL : GetRepPtr()->getRealPointer();
}
template<class T, class REP, class ACCESS>
bool SmartPtr<T,REP,ACCESS>::operator == ( const SmartPtrBase& ptr ) {
return m_rep == ptr.m_rep;
}
template<class T, class REP, class ACCESS>
bool SmartPtr<T,REP,ACCESS>::operator == ( const T* ptr ) {
if( ! IsNull() ) {
return GetRepPtr()->getRealPointer() == ptr;
}
return ptr == NULL;
}
template<class T, class REP, class ACCESS>
bool SmartPtr<T,REP,ACCESS>::operator != ( const SmartPtrBase& ptr ) {
return m_rep != ptr.m_rep;
}
template<class T, class REP, class ACCESS>
bool SmartPtr<T,REP,ACCESS>::operator != ( const T* ptr ) {
return ! (operator ==( ptr ));
}
template<class T, class REP, class ACCESS>
bool SmartPtr<T,REP,ACCESS>::IsNull() const {
return m_rep == NULL;
}
template<class T, class REP, class ACCESS>
long SmartPtr<T,REP,ACCESS>::GetRefCount() const {
ASSERT( ! IsNull() );
return GetRepPtr()->m_counter;
}
template<class T, class REP, class ACCESS>
REP* SmartPtr<T,REP,ACCESS>::GetRepPtr() const {
return (REP*)m_rep;
}
template<class T, class REP, class ACCESS>
void SmartPtr<T,REP,ACCESS>::IncrRefCount() {
if( ! IsNull() ) {
GetRepPtr()->incrRefCount();
}
}
template<class T, class REP, class ACCESS>
void SmartPtr<T,REP,ACCESS>::DecrRefCount() {
if( ! IsNull() ) {
if( GetRepPtr()->decrRefCount() <= 0 ) {
REP* rep = (REP*)m_rep;
delete rep;
}
m_rep = NULL;
}
}
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
//
// Helper classes for easier use of the SmartPtr class
//
/////////////////////////////////////////////////////////////////////////////
template<class T, class REP = CRefCountRep<T>, class ACCESS = T*>
class RefCountPtr : public SmartPtr<T, REP, ACCESS> {
// Constructors and destructor
public:
// Default constructor and destructor
RefCountPtr() {};
~RefCountPtr() {};
// Copy constructor
RefCountPtr( const RefCountPtr& ptr )
: SmartPtr<T,REP,ACCESS>( ptr )
{};
RefCountPtr( const SmartPtrBase& ptr )
: SmartPtr<T,REP,ACCESS>( ptr )
{};
RefCountPtr( const T* ptr )
: SmartPtr<T,REP,ACCESS>( ptr )
{};
// Assignment Operators
public:
RefCountPtr& operator = ( const RefCountPtr& ptr ) {
CopyFrom( ptr );
return *this;
}
RefCountPtr& operator = ( const T* ptr ) {
CopyFrom( ptr );
return *this;
}
RefCountPtr& operator = ( const SmartPtrBase& ptr ) {
CopyFrom( ptr );
return *this;
}
};
/////////////////////////////////////////////////////////////////////////////
template<class T, class REP = CSyncAccessRep<T>, class ACCESS = CSyncAccess<T> >
class SyncPtr : public SmartPtr<T, REP, ACCESS> {
// Constructors and destructor
public:
// Default constructor and destructor
SyncPtr() {};
~SyncPtr() {};
// Copy constructor
SyncPtr( const SyncPtr& ptr )
: SmartPtr<T,REP,ACCESS>( ptr )
{};
SyncPtr( const SmartPtrBase& ptr )
: SmartPtr<T,REP,ACCESS>( ptr )
{};
SyncPtr( const T* ptr )
: SmartPtr<T,REP,ACCESS>( ptr )
{};
// Assignment Operators
public:
SyncPtr& operator = ( const SyncPtr& ptr ) {
CopyFrom( ptr );
return *this;
}
SyncPtr& operator = ( const T* ptr ) {
CopyFrom( ptr );
return *this;
}
SyncPtr& operator = ( const SmartPtrBase& ptr ) {
CopyFrom( ptr );
return *this;
}
};
/////////////////////////////////////////////////////////////////////////////
template<class T, class REP = CSyncRefCountRep<T>, class ACCESS = CSyncAccess<T> >
class SyncRefCountPtr : public SmartPtr<T, REP, ACCESS> {
// Constructors and destructor
public:
// Default constructor and destructor
SyncRefCountPtr() {};
~SyncRefCountPtr() {};
// Copy constructor
SyncRefCountPtr( const SyncRefCountPtr& ptr )
: SmartPtr<T,REP,ACCESS>( ptr )
{};
SyncRefCountPtr( const SmartPtrBase& ptr )
: SmartPtr<T,REP,ACCESS>( ptr )
{};
SyncRefCountPtr( const T* ptr )
: SmartPtr<T,REP,ACCESS>( ptr )
{};
// Assignment Operators
public:
SyncRefCountPtr& operator = ( const SyncRefCountPtr& ptr ) {
CopyFrom( ptr );
return *this;
}
SyncRefCountPtr& operator = ( const T* ptr ) {
CopyFrom( ptr );
return *this;
}
SyncRefCountPtr& operator = ( const SmartPtrBase& ptr ) {
CopyFrom( ptr );
return *this;
}
};
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
//
// Examples on how to use these classes.
//
// There are 3 cases:
// 1. Reference Counting
// 2. Object Level Thread Synchronization
// 3. Object Level Thread Synchronization AND Reference Counting
//
/*
Let's have a class CSomething
1. Reference Counting on CSomething
------------------------------------
class CSomething {
CSomething();
~CSomething();
.....
void do();
};
typedef RefCountPtr<CSomething> LPSOMETHING;
void TestFunct() {
LPSOMETHING p1 = new CSomething;
LPSOMETHING p2 = p1;
if( p1 == NULL ) {
....
}
p2->do();
p1 = NULL;
} // Here the object pointed by p2 WILL BE destroyed automatically
/////////////////////////////////////////////////////////////////////////////
2. Object Level Thread Synchronization for objects of CSomething
---------------------------------------------------------
class CSomething {
CSomething();
~CSomething();
.....
void do();
};
typedef SyncPtr<CSomething> LPSOMETHING;
void TestFunct() {
LPSOMETHING p1 = new CSomething;
LPSOMETHING p2 = p1;
if( p1.IsNULL() ) {
....
}
StartThread( p1 );
p2->do(); // Synchronized with the other thread
p1 = NULL;
} // Here the object pointed by p2 will NOT be destroyed automatically
void ThreadFunc( LPSOMETHING p ) {
p->do(); // Synchronized with the other thread
}// Here the object pointed by p will NOT be destroyed automatically
/////////////////////////////////////////////////////////////////////////////
3. Object Level Thread Synchronization and Reference Counting
for objects of CSomething
---------------------------------------------------------
class CSomething {
CSomething();
~CSomething();
.....
void do();
};
typedef SyncRefCountPtr<CSomething> LPSOMETHING;
void TestFunct() {
LPSOMETHING p1 = new CSomething;
LPSOMETHING p2 = p1;
if( p1.IsNULL() ) {
....
}
StartThread( p1 );
p2->do(); // Synchronized with the other thread
p1 = NULL;
} // Here the object pointed by p2 WILL BE destroyed automatically
// if p in ThreadFunc has already released the object
void ThreadFunc( LPSOMETHING p ) {
p->do(); // Synchronized with the other thread
}// Here the object pointed by p WILL BE destroyed automatically
// if p2 in TestFunc has already released the object
/////////////////////////////////////////////////////////////////////////////
WARNING: Don't use a code like this
CSomething* ptr = new CSomething(); // A real pointer
LPSOMETHING p1 = ptr;
LPSOMETHING p2 = ptr; // This will lead to 2 (two)
// representation objects.
// So you will not have nor proper
// grabage collection nor proper
// thread synchronization
if( p1 != p2 ) { // The comparison will say these
ASSERT( FALSE ); // point to different objects
} // even you think it is the same
/////////////////////////////////////////////////////////////////////////////
sizeof( CRITICAL_SECTION ) 24
sizeof( CRefCountRep ) 8
sizeof( CSyncAccessRep ) 32
sizeof( CSyncRefCountRep ) 32
sizeof( CSyncAccess ) 8
sizeof( SmartPtr ) 4
sizeof( CSomething* ) 4
sizeof( int ) 4
*/
#endif // _SMARTPTR_H_
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -