帶有引用計數的智能指針

來自《高質量程序設計指南 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;
};
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章