您的位置:首页 > 编程语言 > C语言/C++

基于灵巧指针和引用计数的String类

2014-03-12 10:07 447 查看
/**
*利用灵巧指针和引用计数功能实现string类
**/

//类头文件

//smart pointer用来管理类的指针成员,避免内存泄露
template <class T>
class RCPtr
{
public:
RCPtr(T* realPtr = 0);
RCPtr(const RCPtr&);
~RCPtr();
RCPtr& operator=(const RCPtr&);
T* operator->() const;
T& operator*() const;
private:
T* pointee;
void Init();
};

//用于进行引用计数功能的虚基类
class RCObject()
{
public:
void AddReference();
void RemoveReference();
void MarkUnshareable();
bool IsShareable() const;
bool IsShared() const;
protected:
RCObject();
RCObject(const RCObject&);
RCObject& operator=(const RCObject&);
virtual ~RCObject() = 0;
private:
int refCount;
bool shareable;
};

//对string进行引用计数和灵巧指针的应用
class String
{
public:
//没有拷贝构造和赋值以及析构,编译器自动生成
//并且由于灵巧指针的存在,调用StringValue的拷贝,完成自己的功能
String(const char* value = "");
const char& operator[](int index) const;
char& operator[](int index);
private:
//StringValue继承RCObject,从而实现了引用计数功能,在父类进行计数控制
struct StringValue:public RCObject
{
char* data;
StringValue(const char* initValue);
StringValue(const StringValue&);
void Init(const char* initValue);
~StringValue();
};
private:
//灵巧指针
RCPtr<StringValue> value;
};

//实现文件RCObject
RCObject::RCObject():refCount(0),shareable(true){}

//虚基类引用计数为0,是为了让用户控制AddReference
RCObject::RCObject(const RCObject&):refCount(0),shareable(true){}

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

RCObject::~RCObject(){}

void RCObject::addReference()
{
++refCount;
}

void RCObject::removeReference()
{
if(--refCount==0)
delete this;
}

bool RCObject::isShareable() const
{
return shareable;
}

bool RCObject::isShared() const
{
//引用最少为2才被引用了,否则只有自身
return refCount>1;
}

//实现文件RCPtr
template<class T>
void RCPtr<T>::Init()
{
if(pointee==0)
return;
if(!pointee->isShareable())
{
pointee = new T(*pointee);
}
pointee->addReference();
}

template<class T>
RCPtr<T>::RCPtr(T* realPtr):pointee(realPtr)
{
Init();
}

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

template<class T>
RCPtr<T>::~RCPtr()
{
if(pointee)
pointee->RemoveReference();
}

template<class T>
RCPtr<T>& RCPtr<T>::operator=(const RCPtr& rhs)
{
if(pointee != rhs.pointee)
{
if(pointee)
pointee->RemoveReference();
pointee = rhs.pointee;
Init();
}
return *this;
}

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

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

//String::StringValue的实现
void StringValue::Init(const char* initValue)
{
data = new char[strlen(initValue)+1];
strcpy(data,initValue);
}

StringValue::StringValue(const char* initValue)
{
Init(initValue);
}

StringValue::StringValue(const StringValue& rhs)
{
Init(rhs.data);
}

StringValue::~StringValue()
{
delete []data;
}

//String的实现
String::String(const char* initValue)value(new StringValue(initValue))
{

}

const char& String::operator[](int index) const
{
return value->data[index];
}
//由于不能确定非const的[]是读还是写,所以都按照写来操作
//从新分配内存,并设定为不可共享状态
char& String::operator[](int index)
{
if(value->IsShared())
{
value = new StringValue(value->data);
}
value->MarkUnshareable();
return value->data[index];
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息