📄 smartptr.h
字号:
GaSmartPtr(const GaSmartPtr<T>& ptr) : _lock(0)
{
Lock( ptr );
// add new reference to smart location
GaSmartStorage<T>::AddReference( ptr._location );
_location = ptr._location;
_data = _location ? _location->_data : NULL;
Unlock( ptr );
}
/// <summary>Default constructor, initializes pointer as <c>NULL</c> pointer.
/// Creation of smart pointer and counting of references is thread-safe.</summary>
GaSmartPtr() : _location(NULL),
_data(NULL),
_lock(0) { }
/// <summary>Decrements number of references to data. If there is no more references, memory used my data is freed and object is destroyed.
/// Destruction of smart pointer is thread-safe.</summary>
~GaSmartPtr()
{
Lock();
GaSmartStorage<T>::RemoveReference( _location );
Unlock();
}
/// <summary>Operator provides access to data to which smart pointer points. This method is thread safe, but it cannot be guaranteed
/// that memory will not be freed if some other thread changes pointer after address is returned.</summary>
/// <returns>Operator returns pointer to user data.</returns>
inline T* GACALL operator ->() const { return _data; }
/// <summary>Operator provides access to data to which smart pointer points. This method is thread safe, but it cannot be guaranteed
/// that memory will not be freed if some other thread changes pointer after address is returned.</summary>
/// <returns>Operator returns reference to user data.</returns>
inline T& GACALL operator *() const { return *_data; }
/// <summary>Sets smart pointer to points to same location as <c>rhs</c> pointer.
/// It also decrements number of references of old smart locationa and increments number of new smart location.
/// If number of references of old location reached zero, this operator frees used memory. This operator is thread-safe.</summary>
/// <param name="rhs">smart pointer which holds address to which <c>this</c> pointer should point.</param>
/// <returns>Operator returns reference to <c>this</c> object.</returns>
inline GaSmartPtr<T>& GACALL operator =(const GaSmartPtr<T>& rhs)
{
if( this != &rhs )
{
Lock( rhs );
if( rhs._location != _location )
{
// remove old reference
GaSmartStorage<T>::RemoveReference( _location );
// new reference
GaSmartStorage<T>::AddReference( rhs._location );
_location = rhs._location;
_data = _location ? _location->_data : NULL;
}
Unlock( rhs );
}
return *this;
}
/// <summary>Sets smart pointer to points to <c>rhs</c> smart location for storing data.
/// It also decrements number of references of old smart locationa and increments number of new smart location.
/// If number of references of old location reached zero, this operator frees used memory. This operator is thread-safe.</summary>
/// <param name="rhs">reference to smart location to which <c>this</c> pointer should point.</param>
/// <returns>Operator returns reference to <c>this</c> object.</returns>
inline GaSmartPtr<T>& GACALL operator =(GaSmartStorage<T>& rhs)
{
Lock();
if( &rhs != _location )
{
// remove old reference
GaSmartStorage<T>::RemoveReference( _location );
// new reference
GaSmartStorage<T>::AddReference( &rhs );
_location = &rhs;
_data = _location ? _location->_data : NULL;
}
Unlock();
return *this;
}
/// <summary>This operator makes new instance of <see cref="GaSmartStorage" /> and binds unmanaged memory to the smart storage and
/// sets pointer to it. It also decrements number of references of old smart locationa and increments number of new smart location.
/// If number of references of old location reached zero, this operator frees used memory. This operator is thread-safe.</summary>
/// <param name="rhs">raw pointer to user data which should be managed.</param>
/// <returns>Operator returns reference to <c>this</c> object.</returns>
inline GaSmartPtr<T>& GACALL operator =(T* rhs)
{
Lock();
if( &rhs != _data )
{
GaSmartStorage<T>* location = GaSmartStorage<T>::MakeInstanceDirect( rhs );
// remove old reference
GaSmartStorage<T>::RemoveReference( _location );
// new reference
GaSmartStorage<T>::AddReference( location );
_location = location;
_data = _location ? _location->_data : NULL;
}
Unlock();
return *this;
}
// Compare to see if two smart pointer points to same safe location.
/// <summary>Compares two smart pointers to see they points to same data. This operator is thread-safe.</summary>
/// <param name="rhs">the second smart pointer in the expression.</param>
/// <returns>Operator returns true if two pointers point to same location.</returns>
inline bool GACALL operator ==(const GaSmartPtr<T>& rhs) const { return _location == rhs._location; }
/// <summary>This method is thread-safe.</summary>
/// <returns>Method returns raw pointer to user data.</returns>
inline T* GACALL GetRawPtr() const { return _data; }
/// <summary>Checks pointer against <c>NULL</c> value. This method is thread-safe.</summary>
/// <returns>Returns <c>true</c> if this is <c>NULL</c> pointer.</returns>
inline bool GACALL IsNULL() const { return !_data; }
private:
/// <summary>This method prevents concurrent changes of smart pointer by locking it.</summary>
inline void Lock() const
{
// sections are very short so spin-lock is used
SPINLOCK( _lock );
}
/// <summary>This method prevents concurrent changes of <c>this</c> and <c>second</c> smart pointers and it is used
/// when value of one pointer is assigning to another (<c>operator =</c> or copy constructor). Order of pointer locking is
/// defined by order of addresses of pointers' objects to prevent deadlocks (first is locked pointer which object has lower address).</summary>
/// <param name="second">the second pointer which is used in expression.</param>
inline void Lock(const GaSmartPtr<T>& second) const
{
// sections are very short so spin-lock is used
// pointer sare locked in order in which address are ordered to prevent deadlocks
if( this < &second )
{
SPINLOCK( _lock );
SPINLOCK( second._lock );
}
else
{
SPINLOCK( second._lock );
SPINLOCK( _lock );
}
}
/// <summary>This method unlocks changes of smart pointer.</summary>
inline void Unlock() const { _lock = 0; }
/// <summary>This method unlocks changes of this and second smart pointers, it is used after assigning of values
/// from one smart pointer to another is done (<c>operator =</c> or copy constructor).</summary>
/// <param name="second">the second pointer whic is used in expression.</param>
inline void Unlock(const GaSmartPtr<T>& second)
{
_lock = 0;
second._lock = 0;
}
public:
/// <summary><c>NullPtr</c> is global constant <c>NULL</c> pointer for <c>T</c> type.</summary>
static const GaSmartPtr<T> NullPtr;
};// END CLASS DEFINITION GaSmartPtr
// NULL pointer
template <typename T>
const GaSmartPtr<T> GaSmartPtr<T>::NullPtr;
} // Common
#endif //__GA_SMART_PTR_H__
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -