我做了一个引用计数智能指针类。我的目标是用适当的文档创建一个“最小”但“通用”的智能指针类。这基本上是为了教育目的。
我想有一些关于异常处理、代码清晰性、注释、API的易用性等方面的评论,如果代码是“工业级别”的话,我也会发表评论。
#ifndef SMARTPTR_HPP
#define SMARTPTR_HPP
#include <algorithm>
namespace smartptrnamespace
{
//
// Basic reference counting smart pointer (no overloaded Bool magic, etc).
// Ownership of memory on heap is shared amongst objects of this
// class (shared ownership) i.e., no new object of T type is created
// by this class.
// Objects of this class are:
// 1. nothrow-copy-assignable
// 2. nothrow-copy-constructible
// 3. nothrow-destructible, if T is nothrow-destructible
// 4. suitable for storage in a STL container like List, Deque etc.
// Strong exception guarantee
//
// Sample Usage:
// SmartPtr<T> sPtr1 (new T); // sPtr1 refers to object of T type
// SmartPtr<T> sPtr2; // sPtr2 refers to no object
// if (!sPtr2.isAssigned ()) // SmartPtr::isAssigned() returns false if no reference is being held
// cout << "sPtr2 is not holding any reference" << endl;
// sPtr2 = new T; // make a new oject of T and pass ownership to sPtr
//
template<class T>
class SmartPtr
{
public:
// create a new object which is not
// refering to any object on heap.
// no-throw guarantee
explicit SmartPtr ()
: m_pT (NULL),
m_pRefCount (NULL)
{
}
// new object will point to a memory location on heap given by 'pObj'
// Strong exception guarantee
explicit SmartPtr (T *pObj)
: m_pT (pObj),
m_pRefCount (NULL)
{
try
{
m_pRefCount = new int;
}
catch (...)
{
checkedDelete (m_pT);
throw;
}
*m_pRefCount = 1;
}
// new object will refer to same memory on heap as 'rObj'
// no-throw guarantee
SmartPtr (const SmartPtr<T> &rObj)
: m_pT(rObj.m_pT),
m_pRefCount(rObj.m_pRefCount)
{
if (m_pRefCount != NULL)
(*m_pRefCount)++;
}
// make 'rObj' and 'this' will refer to same object on heap
// no-throw guarantee
SmartPtr& operator= (const SmartPtr<T> &rObj)
{
// uses copy-and-swap idiom
this_type(rObj).swap(*this);
return *this;
}
// assign this smart pointer to another object on heap
// Strong exception guarantee
SmartPtr& operator= (T *pTObj)
{
// try and setup memory for reference counter
int *pNewRefCount;
try
{
pNewRefCount = new int;
}
catch (...)
{
delete pTObj;
throw;
}
// stop referring to previous object
updateCountAndTriggerDelete ();
// start referring to new object
m_pRefCount = pNewRefCount;
*m_pRefCount = 1;
m_pT = pTObj;
return *this;
}
// no-throw guarantee
~SmartPtr ()
{
updateCountAndTriggerDelete ();
}
// returns true if this object is holding a reference
// to an object on heap
// no-throw guarantee
bool isAssigned()
{
return !(m_pT == NULL);
}
// no-throw guarantee
T* operator->()
{
return m_pT;
}
// no-throw guarantee
T& operator*()
{
return *m_pT;
}
private:
// make sure we dont delete a incomplete type pointer
// no-throw guarantee
template <class S>
void checkedDelete (S* pSObj)
{
typedef char type_must_be_complete[ sizeof(S)? 1: -1 ];
(void) sizeof(type_must_be_complete);
delete pSObj;
}
// count the references and delete it if this is last reference
// no-throw guarantee
void updateCountAndTriggerDelete ()
{
if (m_pRefCount != NULL)
{
(*m_pRefCount)--;
// if this is last reference delete the memory
if (*m_pRefCount == 0)
{
checkedDelete (m_pRefCount);
checkedDelete (m_pT);
}
}
}
// swap the pointer values of 'rObj' with values of 'this'
// no-throw guarantee
void swap (SmartPtr<T> &rObj)
{
std::swap (m_pT, rObj.m_pT);
std::swap (m_pRefCount, rObj.m_pRefCount);
}
// pointer to memory location of object
T *m_pT;
// pointer to memory location where 'reference' count of
// object pointed to by m_pT is kept
int *m_pRefCount;
typedef SmartPtr<T> this_type;
};
} // namespace smartptrnamespace
#endif // SMARTPTR_HPP发布于 2013-04-18 21:40:24
一些非专家的评论:
m_pRefCount成为指向int的指针而不是简单的int有什么好处吗?checkedDelete来删除指向您自己创建的int的指针?如果您不使用checkedDelete作为本地int,那么函数可以采用模板类型T而不是新的类S。难道没有更好的方法来检查不完整类型吗?(表现出我的无知)有必要吗?发布于 2013-04-19 08:59:44
std::(tr1::)shared_ptr。他们有着广为人知的设计API,没有必要在没有充分理由的情况下发明新的东西。operator bool,而不是isAssigned,它应该是const。 In C++这将是explicit operator bool() const,在C++03 -安全-bool成语中.unique_ptr,并使用它暂时拥有对象:显式SmartPtr (T *pObj):m_pT(pObj),m_pRefCount() { unique_ptr temp(pObj);m_pRefCount = new (1);temp.release()};operator= (T *pTObj)应该使用SmartPtr (T *pObj) ctor和dtor void operator= (T *pTObj) { SmartPtr(pTObj).swap(*this);}SmartPtr<T>(NULL)坏了。typedef SmartPtr this_type; (没有<T>)https://codereview.stackexchange.com/questions/25214
复制相似问题