技术(5)—引用计数

来源:互联网 发布:vidconvert mac注册机 编辑:程序博客网 时间:2024/06/05 15:47

Item 29 引用计数

这是我看这系列以来,感觉最难的一部分内容,比较综合。

使用引用计数改善效率的最适当时机:

(1)相对多数的对象共享相对少量的实值。

(2)对象实值的产生或销毁的成本很高。

在书中实现了一个用来支持引用计数的基类和智能指针类,具体如下:

RCObject:

头文件:

class RCObject{protected:RCObject(void);RCObject(const RCObject& rhs);RCObject& operator=(const RCObject& rhs) {return *this;}virtual ~RCObject()=0;public:void addReference();void removeReference();void markUnshareable();bool isShareable() const;bool isShared() const;private:int refCount;bool shareable;};

实现文件:

RCObject::RCObject(void):refCount(0),shareable(true){}RCObject::RCObject(const RCObject&):refCount(0),shareable(true){}RCObject::~RCObject(void){}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;}

可以注意,构造函数和拷贝构造函数的refCount都是设为0的。其他的改动引用计数的指责交给了智能指针。

#include "RCObject.h"template <typename T>class RCPtr{public:RCPtr(T* realPtr=0);RCPtr(const RCPtr& rhs);~RCPtr(void);RCPtr& operator=(const RCPtr& rhs);const T* operator->() const;T* operator->();const T& operator*() const;T& operator*();private:struct CountHolder:public RCObject{~CountHolder() {delete pointee;}T* pointee;};CountHolder* counter;void init();void makeCopy();};template <typename T>void RCPtr<T>::init(){if(counter->isShareable()==false){T* oldValue=counter->pointee;counter=new CountHolder();counter->pointee=new T(*oldValue);}counter->addReference();}template <typename T>RCPtr<T>::RCPtr(T* realPtr):counter(new CountHolder()){counter->pointee=realPtr;init();}template <typename T>RCPtr<T>::RCPtr(const RCPtr& rhs):counter(rhs.counter){init();}template <typename T>RCPtr<T>& RCPtr<T>::operator=(const RCPtr& rhs){if(counter!=rhs.counter){counter->removeReference();counter=rhs.counter;init(); }return *this;}template <typename T>RCPtr<T>::~RCPtr(){counter->removeReference();}template <typename T>const T* RCPtr<T>::operator->() const{return counter->pointee;}template <typename T>const T& RCPtr<T>::operator*() const{return *(counter->pointee);}template <typename T>void RCPtr<T>::makeCopy(){T* oldValue=counter->pointee;counter=new CountHolder();counter->pointee=new T(*oldValue);counter->addReference();}template <typename T>T* RCPtr<T>::operator->(){if(counter->isShared()){makeCopy();counter->markUnshareable();}return counter->pointee;}template <typename T>T& RCPtr<T>::operator*(){if(counter->isShared()){makeCopy();counter->markUnshareable();}return *(counter->pointee);}

如果我们对现有库中的某个类采用引用计数的方式,则可以采用如下的方式:




Widget和RCWidget的代码如下:

#include <iostream>using namespace std;class Widget{public:Widget(int s):size(s) {}Widget(const Widget& rhs) {size=rhs.size;}~Widget(void) {}Widget& operator=(const Widget& rhs){if(this==&rhs)return *this;this->size=rhs.size;return *this;}void doThis() {cout<<"doThis()"<<endl;}int showThat() const {cout<<"showThat()"<<endl;return size;}private:int size;};
#include "RCPtr.h"#include "Widget.h"class RCWidget{public:RCWidget(int size):value(new Widget(size)) {}~RCWidget(void) {}void doThis() {value->doThis();}int showThat() const {return value->showThat();}private:RCPtr<Widget> value;};

这样的技术就实现了对已有库中类的引用技术的包装。

即使我们自己去写,也可以实现一个类,用这样的技术去实现引用计数。

我对这部分内容理解的不是很好,先记录下来,慢慢品味。

原创粉丝点击