随笔 - 87  文章 - 279  trackbacks - 0
<2007年10月>
30123456
78910111213
14151617181920
21222324252627
28293031123
45678910

潜心看书研究!

常用链接

留言簿(19)

随笔分类(81)

文章分类(89)

相册

ACM OJ

My friends

搜索

  •  

积分与排名

  • 积分 - 214751
  • 排名 - 116

最新评论

阅读排行榜

评论排行榜

发觉计算机很多东西都是相同的,记得操作系统时候学过这一概率 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了

posted on 2008-04-09 21:36 阅读(539) 评论(0)  编辑 收藏 引用 所属分类: C++之梦

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   博问   Chat2DB   管理