來自《高質量程序設計指南 C/C++》
template<class T>
class INonintrusiveRefcountManager {
public:
virtual size_t addRef() = 0;
virtual size_t release() = 0;
virtual T* realObject() = 0;
virtual const T* realObject() const = 0;
};
template<class T>
class DefaultNonintrusiveRefcountMgr
: public INonintrusiveRefcountManager<T> {
public:
explicit DefaultNonintrusiveRefcountMgr(T *rep = nullptr)
: m_pData(rep), m_refCount(1) {}
DefaultNonintrusiveRefcountMgr(const DefaultNonintrusiveRefcountMgr<T>&) = delete;
void operator= (const DefaultNonintrusiveRefcountMgr<T>&) = delete;
virtual ~DefaultNonintrusiveRefcountMgr() { }
virtual size_t addRef() {
// ::InterlockedIncrement((long*)&m_refCount); // 併發
return ++m_refCount;
}
virtual size_t release() {
// ::InterlockDecrement((long*)&m_refCount);
--m_refCount;
if (m_refCount == 0) {
this->_Dstroy();
delete this;
return 0;
}
return m_refCount;
}
virtual T* realObject() {
return m_pData;
}
virtual const T* realObject() const {
return m_pData;
}
protected:
void _Distroy() {
delete m_pData;
m_pData = nullptr;
}
T* m_pData;
size_t m_refCount;
};
template<class T, class RefcountManager = DefaultNonintrusiveRefcountMgr<T> >
class SmartPtr {
typedef typename RefcountManager::DataObjectType DataObjectType;
SmartPtr() : m_rep(nullptr) {}
explicit SmartPtr(DataObjectType *pointee) {
if (pointee != nullptr)
m_rep = new RefcountManager(pointee);
else
m_rep = nullptr;
}
SmartPtr(const SmartPtr<T, RefcountManager>& other) {
if ((m_rep = other.m_rep) != nullptr)
m_rep->addRef();
}
~SmartPtr() {
if (m_ref != nullptr)
m_ref->release();
}
SmartPtr<T, RefcountManager>&
operator=(const SmartPtr<T, RefcountManager>& other) {
if (this != &other && m_rep != other.m_rep) {
if (m_rep != nullptr) {
m_rep->release();
}
if ((m_rep = other.m_rep) != nullptr) {
m_rep->addRef();
}
}
return *this;
}
SmartPtr<T, RefcountManager>& operator= (DataObjectType* pointee) {
RefcontManager *pTemp = nullptr;
if (pointee != nullptr) {
pTemp = new RefcountManager(pointee);
}
if (m_rep != nullptr) {
m_rep->release();
}
m_rep = pTemp;
return *this;
}
bool operator!() const {
return ((m_rep == nullptr) || m_rep->realObject() == nullptr) ?
true : false;
}
operator void*() const {
return (m_rep == nullptr ? nullptr : m_rep->realObject());
}
DataObjectType* operator->() {
assert(m_rep != nullptr && m_rep->realObject() != nullptr);
return m_rep->realObject();
}
const DataObjectType* operator->() const {
assert(m_rep != nullptr && m_rep->realObject() != nullptr);
return m_rep->realObject();
}
DataObjectType& operator*() {
assert(m_rep != nullptr && m_rep->realObject() != nullptr);
return *(m_rep->realObject());
}
// 獲得實值對象指針
DataObjectType* _ugly_method() {
return (m_rep == nullptr ? nullptr : m_rep->realObject());
}
const DataObjectType* _ugly_method() const {
return (m_rep == nullptr ? nullptr : m_rep->realObject());
}
};
accelerated C++
template<class T>
SmartPtr<T>& SmartPtr<T>::operator=(const SmartPtr& rhs) {
++*rhs.refptr;
// 先加後減可以避免自賦值
if (--*refptr == 0) {
delete refptr;
delete p;
}
refptr = rhs.refptr;
p = rhs.p;
return *this;
}
template<class T>
T& SmartPtr<T>::operator*() const {
if (p != nullptr)
return *p;
throw std::runtime_error("unbound Ptr");
}
template<class T>
SmartPtr<T>::~SmartPtr() {
if (--*refPtr == 0) {
delete refptr;
delete p;
}
}
More Effective C++
class RCObject {
public:
RCObject();
RCObject(const RCObject& rhs);
RCObject& operator=(const RCObject& rhs);
virtual ~RCObject() = 0;
void addReference();
void removeReference();
void markUnshareable();
bool isShareable() const;
bool isShared() const;
private:
size_t refCount;
bool shareable;
};
RCObject::RCObject() : refCount(0), shareable(true) { }
RCObject::RCObject(const RCObject& rhs) : refCount(0), shareable(true){ }
RCObject& RCObject::operator= (const RCObject & rhs) { return *this; }
RCObject::~RCObject() { }
void RCObject::addReference() { ++refCount; }
void RCObject::removeReference() {
if (--refCount == 0)
delete this;
}
void RCObject::markUnshareable() { shareable = false; }
bool RCObject::isShareable() const { return shareable; }
bool RCObject::isShared() const { return refCount > 1; }
template<class T>
class RCPtr {
public:
RCPtr(T* realPtr = nullptr);
RCPtr(const RCPtr& rhs);
~RCPtr();
RCPtr& operator= (const RCPtr& rhs);
T* operator->() const;
T& operator*() const;
private:
struct CounterHolder : public RCObject {
~CounterHolder() { delete pointee; }
T* pointee;
};
CounterHolder *counter;
void init();
};
template<class T>
void RCPtr<T>::init() {
if (counter->isShareable() == false) {
T* oldValue = counter->pointee;
counter = new CounterHolder;
counter->pointee = oldValue ? new T(*oldValue) : 0;
}
counter->addReference();
}
template<class T>
RCPtr<T>::RCPtr(T* realPtr) : pointee(realPtr) {
init();
}
template<class T>
RCPtr<T>::RCPtr(const RCPtr& rhs) : counter(rhs.counter) { init(); }
template<class T>
RCPtr<T>& RCPtr<T>::operator=(const RCPtr& rhs) {
if (counter != rhs.counter) {
if (counter != nullptr) counter->removeReference();
counter = rhs.counter;
init();
}
return *this;
}
template<class T>
T* RCPtr<T>::operator->() const {
return counter->pointee;
}
template<class T>
T& RCPtr<T>::operator*() const {
return *(couner->pointee);
}
template<class T>
RCPtr<T>::~RCPtr() {
if (counter != nullptr)
counter->removeReference;
}
More Exceptional C++
template<class T>
class shared_ptr {
public:
class implement {
public:
explicit implement(T* p):pointee(p), refs(1) {}
T* pointee;
size_t refs;
};
explicit shared_ptr(T* p) {
impl = new implement(p);
}
shared_ptr(const shared_ptr<T>& rhs):impl(rhs.impl){
increase();
}
~shared_ptr() {
decrease();
}
T& operator*() const{
return *(impl->pointee);
}
T* operator->() const{
return impl->pointee;
}
shared_ptr<T>& operator=(const shared_ptr<T>& rhs) {
if (this != rhs && impl != rhs.impl){
decrease();
impl = rhs.impl;
increase();
}
}
private:
void decrease() {
if (--impl->refs == 0) delete impl;
}
void increase() {
++impl->refs;
}
implement* impl;
};