这次修改主要针对如下几个问题:
(1)防止指向同一个对象的智能指针之间的意外赋值;
(2)使智能指针能够随意地放置在各种容器中,比如STL容器、数组等;
(3)能够对存放智能指针的容器进行排序、合并、切分等等操作,比如调用list.sort()或者std::sort()等算法。
修改后的代码如下:
//
非侵入式引用计数器管理对象接口
template<typename _Ty>
class INonintrusiveRefcountManager {
public:
virtual size_t addRef() = 0; // return new refcount
virtual size_t release() = 0; // return new refcount
virtual _Ty* realObject() = 0;
virtual const _Ty* realObject() const = 0;
};
template<typename _Ty>
class DefaultNonintrusiveRefcountMgr : public INonintrusiveRefcountManager<_Ty> {
public:
typedef _Ty DataObjectType;
explicit DefaultNonintrusiveRefcountMgr(DataObjectType *rep = NULL)
: m_pData(rep), m_refCount(1) { } /*
初始引用计数为
1 */
virtual ~DefaultNonintrusiveRefcountMgr() { }
virtual size_t addRef() { //
引用计数
+1
::InterlockedIncrement((long*)&m_refCount); // WIN32 API
return m_refCount;
}
virtual size_t release() { //
引用计数
-1
::InterlockedDecrement((long*)&m_refCount); // WIN32 API
if (m_refCount == 0) {
this->_Destroy(); //
如果引用计数为
0
,则删除实值对象
delete this;
return 0; // must return 0 quickly!
}
return m_refCount;
}
virtual DataObjectType* realObject() { return m_pData; }
virtual const DataObjectType* realObject() const { return m_pData; }
protected:
void _Destroy() {
delete m_pData; m_pData = NULL; //
销毁实值对象
}
DataObjectType *m_pData;
size_t m_refCount;
private:
//
禁止复制和赋值
DefaultNonintrusiveRefcountMgr(const DefaultNonintrusiveRefcountMgr<_Ty>&);
void operator=(const DefaultNonintrusiveRefcountMgr<_Ty>&);
};
//
非侵入式引用计数智能指针模板
template<
typename _Ty, /*
实值对象类型
*/
typename RefcountManager = DefaultNonintrusiveRefcountMgr<_Ty>
>
class SmartPtr {
public:
typedef typename RefcountManager::DataObjectType DataObjectType;
SmartPtr() : m_rep(NULL) { }
explicit SmartPtr(DataObjectType *pointee) { //
接管
if (pointee != NULL)
m_rep = new RefcountManager(pointee);
else
m_rep = NULL; // m_rep
可能为
NULL
}
SmartPtr(const SmartPtr<_Ty, RefcountManager>& other) { //
复制智能指针
if ((m_rep = other.m_rep) != NULL)
m_rep->addRef(); //
只增引用计数
}
~SmartPtr() {
if (m_rep != NULL)
m_rep->release(); //
释放拥有权
}
SmartPtr<_Ty, RefcountManager>& /
operator=(const SmartPtr<_Ty, RefcountManager>& other) { //
智能指针赋值
if (this != &other && m_rep != other.m_rep) {
if (m_rep != NULL && other.m_rep != NULL
&& m_rep->realObject() == other.m_rep->realObject())
return (*this);
if (m_rep != NULL)
m_rep->release(); //
释放原指针拥有权
if ((m_rep = other.m_rep) != NULL)
m_rep->addRef(); //
只增引用计数
}
return (*this);
}
SmartPtr<_Ty, RefcountManager>& /
operator=(DataObjectType* pointee) { //
接管
if (m_rep != NULL && m_rep->realObject() == pointee)
return (*this);
RefcountManager *pTemp = NULL;
if (pointee != NULL)
pTemp = new RefcountManager(pointee);
if (m_rep != NULL)
m_rep->release();
m_rep = pTemp;
return (*this);
}
bool operator!() const
{ return ((m_rep == NULL || m_rep->realObject() == NULL) ? true : false); }
operator void*() const
{ return (m_rep == NULL ? NULL : m_rep->realObject()); }
DataObjectType* operator->() {
assert(m_rep != NULL && m_rep->realObject() != NULL);
return (m_rep->realObject());
}
const DataObjectType* operator->() const {
assert(m_rep != NULL && m_rep->realObject() != NULL);
return (m_rep->realObject());
}
DataObjectType& operator*() {
assert(m_rep != NULL && m_rep->realObject() != NULL);
return (*(m_rep->realObject()));
}
const DataObjectType& operator*() const {
assert(m_rep != NULL && m_rep->realObject() != NULL);
return (*(m_rep->realObject()));
}
void swap(SmartPtr<_Ty, RefcountManager>& other) {
if (m_rep != other.m_rep)
std::swap(m_rep, other.m_rep);
}
//
获得实值对象的指针
DataObjectType* _ugly_method()
{ return (m_rep == NULL ? NULL : m_rep->realObject()); }
const DataObjectType* _ugly_method() const
{ return (m_rep == NULL ? NULL : m_rep->realObject()); }
private:
RefcountManager *m_rep;
};
template<class T, class S>
inline bool __cdecl operator<(const SmartPtr<T, S>& left, const SmartPtr<T, S>& right)
{
return (*left < *right);
}
template<class T, class S>
inline bool __cdecl operator==(const SmartPtr<T, S>& left, const SmartPtr<T, S>& right)
{
return (*left == *right);
}
template<class T, class S>
inline bool __cdecl operator>(const SmartPtr<T, S>& left, const SmartPtr<T, S>& right)
{
return (*right < *left);
}
template<class T, class S>
inline bool __cdecl operator>=(const SmartPtr<T, S>& left, const SmartPtr<T, S>& right)
{
return !(*left < *right);
}
template<class T, class S>
inline bool __cdecl operator<=(const SmartPtr<T, S>& left, const SmartPtr<T, S>& right)
{
return !(*right < *left);
}
template<class T, class S>
inline bool __cdecl operator!=(const SmartPtr<T, S>& left, const SmartPtr<T, S>& right)
{
return !(*right == *left);
}
template<class T, class S>
inline void swap(SmartPtr<T, S>& left, SmartPtr<T, S>& right)
{
left.swap(right);
}