More Effective 的 Reference Counting

More Effective 的 Reference Counting
发觉计算机很多东西都是相同的,记得操作系统时候学过这一概率 copy on write,在Reference Counted中彻底用到,代码的设计确实精妙,可以在不修改客户端得类,利用RCIPtr间接指针,对客户端的类实现引用计数,太妙了,详细见代码吧,代码中Widget为已有的客户端的类,RCIPtr是一个间接指针,RCObject是引用计数的基类,所有需要引用计数的类都必须继承他,换句话说,RCObject类将引用计数逻辑封装了,而RCIPtr则是连接客户端类的纽带.
代码如下:
RCIPtr.h
#ifndef RCIPTR_H
#define  RCIPTR_H

#include 
" RCObject.h "

template
< class  T >
class  RCIPtr  {
public :
    RCIPtr(T
* realPtr = 0);                        
    RCIPtr(
const RCIPtr& rhs);
    
~RCIPtr();
    RCIPtr
& operator=(const RCIPtr& rhs);
    
const T* operator->() const;                    //const version ->
    T* operator->();                                
    
const T& operator*() const;                    //const version *
    T& operator*();
    
int getRefCount() const;                    //测试用,获取指针所指向的对象的引用数
private :
    
struct CountHolder : public RCObject {                //T的实际的指针保寸的地方
        ~CountHolder() {delete pointee;};
        T
* pointee;
    }
;
    CountHolder 
*counter;
    
void init();                            //初始化公共代码
    void makeCopy();                        //Copy On Write的调用函数
}
;

#include 
" RCIPtr.cpp "

#endif

RCIPtr.cpp
#ifdef RCIPTR_H 

template
< class  T >  
void  RCIPtr < T > ::init()  {
    
if (counter->isShareable() == false{
        T
* oldValue = counter->pointee;
        counter 
= new CountHolder;
        counter
->pointee = new T(*oldValue);
    }

    counter
->addReference();
}


template
< class  T >                                  
void  RCIPtr < T > ::makeCopy()  {
    
if (counter->isShared()) {
        counter
->removeReference();
        T
* oldValue = counter->pointee;    
        counter 
= new CountHolder;
        counter
->pointee = new T(*oldValue);
        counter
->addReference();
    }

}


template
< class  T >  
RCIPtr
< T > ::RCIPtr(T *  realPtr) : counter( new  CountHolder)  {
    counter
->pointee = realPtr;
    init();
}


template
< class  T >  
RCIPtr
< T > ::RCIPtr( const  RCIPtr &  rhs) : counter(rhs.counter)  {
    init();
}


template
< class  T >  
RCIPtr
< T > :: ~ RCIPtr()  {
    counter
->removeReference();
}


template
< class  T >  
RCIPtr
< T >&  RCIPtr < T > :: operator = ( const  RCIPtr &  rhs)  {
    
if (counter != rhs.counter) {
        counter
->removeReference();
        counter 
= rhs.counter;
        init();
    }

    
return *this;
}


template
< class  T >  
const  T *  RCIPtr < T > :: operator -> ()  const   {
    
return counter->pointee;
}
            

template
< class  T >  
T
*  RCIPtr < T > :: operator -> ()  {
    makeCopy(); 
    
return counter->pointee;
}


template
< class  T >                                  
const  T &  RCIPtr < T > :: operator * ()  const   {
    
return *(counter->pointee);
}



template
< class  T >                                  
T
&  RCIPtr < T > :: operator * ()  {
    makeCopy();
    
return *(counter->pointee);
}


template
< class  T >
int  RCIPtr < T > ::getRefCount()  const   {
    
return counter->getRefCount();
}


#endif

RCObject.h
#ifndef RCOBJECT_H
#define  RCOBJECT_H

/**/ /**
 *    base class, 用于reference-counted objects
 
*/

class  RCObject  {
public :
    
void addReference();                        //添加reference
    void removeReference();                        //删除reference
    void markUnshareable();                        //标记object不可共享
    bool isShareable() const;                    //判断object是否可被共享
    bool isShared() const;                        //判断object是否被共享中
    int getRefCount() const;                    //获取对象的引用数
protected :
    RCObject();                                    
//RCObject default-constructor
    RCObject(const RCObject& rhs);                //RCObject copy-constructor 
    RCObject& operator=(const RCObject& rhs);    //RCObject assignment
    virtual ~RCObject() = 0;
private :
    
int refCount;                                //引用计数
    bool shareable;                                //可否共享标记
}
;

#endif

RCObject.cpp
#include  " RCObject.h "

RCObject::RCObject() : refCount(
0 ), shareable( true {
}


RCObject::RCObject(
const  RCObject &  rhs) : refCount( 0 ), shareable( true {
}


RCObject
&  RCObject:: operator   = ( const  RCObject &  rhs)  {
    
return *this;
}


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;
}


int  RCObject::getRefCount()  const   {
    
return refCount;
}


RCObject::
~ RCObject()  {
//    delete this;
}

Widget.h
#ifndef WIDGET_H
#define  WIDGET_H

/**/ /**
 * Widget测试类
 
*/

class  Widget  {
public :
    Widget(
int size);
    Widget(
const Widget& rhs);
    
~Widget();
    Widget
& operator=(const Widget& rhs);
    
void setSize(int size);
    
int getSize() const;
    
void showSize() const;
private :
    
int mSize;
}
;

#endif

Widget.cpp
#include  " Widget.h "
#include 
< iostream >
using   namespace  std;


Widget::Widget(
int  size) : mSize(size)  {
}


Widget::Widget(
const  Widget &  rhs) : mSize(rhs.mSize)  {
}


Widget::
~ Widget()  {
}


Widget
&  Widget:: operator = ( const  Widget &  rhs)  {
    
if (this == &rhs) {
        
return *this;
    }

    mSize 
= rhs.getSize();
    
return *this;
}


void  Widget::setSize( int  size)  {
    mSize 
= size;
}


int  Widget::getSize()  const   {
    
return mSize;
}


void  Widget::showSize()  const   {
    cout 
<< "Size of this Widget is " << mSize << endl;
}

RCWidget.h
#ifndef RCWIDGET_H
#define  RCWIDGET_H

#include 
" RCIPtr.h "
#include 
" Widget.h "

class  RCWidget  {
public :
    RCWidget(
int size);
    
void setSize(int size);
    
int getSize() const;
    
void showSize() const;
    
int getRefCount() const;
private :
    RCIPtr
<Widget> value;
}
;

#endif  

RCWidget.cpp
#include  " RCWidget.h "

RCWidget::RCWidget(
int  size) : value( new  Widget(size))  {
}


void  RCWidget::setSize( int  size)  {
    value
->setSize(size);
}


int  RCWidget::getSize()  const   {
    
return value->getSize();
}


void  RCWidget::showSize()  const   {
    value
->showSize();
}


int  RCWidget::getRefCount()  const   {
    
return value.getRefCount();
}

test.cpp
#include  " RCWidget.h "
#include 
< iostream >
using   namespace  std;

int  main()  {
    RCWidget w(
100);
    RCWidget v(w);
    v.showSize();
    w.showSize();
    cout 
<< "v RCWidget RefCount is " << v.getRefCount() << endl;
    cout 
<< "w RCWidget RefCount is " << w.getRefCount() << endl;
    v.setSize(
20);
    v.showSize();
    w.showSize();
    cout 
<< "v RCWidget RefCount is " << v.getRefCount() << endl;
    cout 
<< "w RCWidget RefCount is " << w.getRefCount() << endl;
    
return 0;
}


Result :
Size of this Widget is 100
Size of this Widget is 100
v RCWidget RefCount is 2
w RCWidget RefCount is 2
Size of this Widget is 20
Size of this Widget is 100
v RCWidget RefCount is 1
w RCWidget RefCount is 1
Press any key to continue

 只要每次写一个类似的RC类,就不用修改客户端已有的类,而又可以实现Reference-Counting了

你可能感兴趣的:(More Effective 的 Reference Counting)