#ifndef _QSHAREPTR_H
#define _QSHAREPTR_H
#include "Utility.h"
namespace Q_COMMON{
template<class T>
class QSharePtr {
public:
class PointerCount {
private:
long refCount;
T* objPtr;
QCMutex lock_;
public:
void add_ref();
void release_ref();
long use_count();
PointerCount(T* p_obj);
~PointerCount();
};
QSharePtr();
explicit QSharePtr(T* ptr);
QSharePtr(const QSharePtr<T> & source);
virtual ~QSharePtr();
QSharePtr<T> & operator=(const QSharePtr<T> & source);
int getRefCount();
T* operator->();
const T* operator->() const;
T& operator*();
inline T* get_pointer() {return p_obj_;}
inline const T* get_pointer() const { return p_obj_;}
public:
operator bool() const;
bool operator!() const;
bool operator<(const QSharePtr<T>& a) const;
private:
PointerCount* p_count_;
T* p_obj_;
};
template<class T>
void QSharePtr<T>::PointerCount::add_ref() {
lock_.lock();
refCount++;
lock_.unlock();
}
template<class T>
void QSharePtr<T>::PointerCount::release_ref() {
lock_.lock();
if(refCount <= 1)
{
//This time is in destructor, so release lock here and do delete this.
lock_.unlock();
delete this;
return;
}else
{
refCount--;
}
lock_.unlock();
}
template<class T>
long QSharePtr<T>::PointerCount::use_count() {
return refCount;
}
template<class T>
QSharePtr<T>::PointerCount::PointerCount(T* p_obj) {
objPtr = p_obj;
refCount = 1;
}
template<class T>
QSharePtr<T>::PointerCount::~PointerCount() {
if(objPtr)
{
delete objPtr;
}
}
template<class T>
QSharePtr<T>::QSharePtr() {
p_count_ = new PointerCount(0);
p_obj_ = 0;
//ptr_->objPtr = NULL;
//ptr_->refCount = 0;
}
template<class T>
QSharePtr<T>::QSharePtr(T* ptr) {
p_count_ = new PointerCount(ptr);
p_obj_ = ptr;
//p_count_->refCount = 1;
//p_count_->add_ref();
}
template<class T>
QSharePtr<T>::QSharePtr(const QSharePtr<T> & source) {
p_count_ = source.p_count_;
p_count_->add_ref();
p_obj_ = source.p_obj_;
}
template<class T>
QSharePtr<T>::~QSharePtr() {
p_count_->release_ref();
}
template<class T>
QSharePtr<T> & QSharePtr<T>::operator=(const QSharePtr<T> & source) {
if(this == &source)
{
return *this;
}
p_count_->release_ref();
p_count_ = source.p_count_;
p_obj_ = source.p_obj_;
if(p_count_)
{
p_count_->add_ref();
}
return *this;
}
template<class T>
int QSharePtr<T>::getRefCount() {
return p_count_->use_count();
}
template<class T>
T* QSharePtr<T>::operator->() {
return p_obj_;
}
template<class T>
const T* QSharePtr<T>::operator->() const {
return p_obj_;
}
template<class T>
T& QSharePtr<T>::operator*() {
return *(p_obj_);
}
template<class T>
QSharePtr<T>::operator bool() const {
return (p_obj_ != 0);
}
template<class T>
bool QSharePtr<T>::operator!() const {
return (p_obj_ == 0);
}
template<class T>
bool QSharePtr<T>::operator<(const QSharePtr<T>& a) const
{
return this->p_obj_ < a.p_obj_;
}
}
#endif