`
dato0123
  • 浏览: 913968 次
文章分类
社区版块
存档分类
最新评论

引用计数型String类的简单实现

 
阅读更多

利用引用计数写时复制这两个特点来实现一个字符串类,为了更好地隐藏类的实现,避免出现下述情况:当对于内联函数定义的改动,对于对象成员大小的改动等导致程序的重新编译,我们可以的代码结构如下:

我们在程序中维护两个不同的头文件,在提供给用户使用的那个公共头文件中,只是告诉用户我们定义了String_ref这个类,并且在String对象中用一个指针指向它

Code
<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->#ifndef STRING_H
#define STRING_H
#include
<iostream>
using namespace std;
#include
<assert.h>

class String_ref; //前向声明代理类

//////////////////////////////////////
// String类声明
//////////////////////////////////////

//简单的引用计数型字符串类
class String
{
private:
String_ref
* proxy; //代理对象指针
public:
String(
const char* = "");
String(
const String& s);
~String();
const String& operator = (const String&);
void ToLower();
int Length()const;
char operator[](int)const;
friend ostream
& operator << (ostream& out,const String& rhs);
};
#endif

另一个头文件String_priv.h是一个私有的头文件,我们并不需要将其分发给用户,它里面包含了对String_ref类的完整声明:

其对应的实现文件String_priv.cpp:

Code
<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->
#include
"String_priv.h"

//////////////////////////////////////
// String_ref实现区
//////////////////////////////////////
String_ref::String_ref(const char * cp):count(0),length(0)
{
this->init(cp);
}
String_ref::
~String_ref()
{
this->release();
}
String_ref::String_ref(
const String_ref& rhs):count(0)
{
this->init(rhs.data);
}
const String_ref& String_ref::operator = (const String_ref& rhs)
{
if(&rhs!=this)
{
delete []
this->data;
init(rhs.data);
}
return *this;
}
char String_ref::operator[] (int index)const
{
assert(index
>=0&&index<strlen(this->data));
return this->data[index];
}
int String_ref::Length()const
{
return this->length;
}
void String_ref::AddRef()
{
++this->count;
}
void String_ref::DecRef()
{
if(--this->count==0)
{
this->release();
}
}
void String_ref::init(const char* cp)
{
this->length = strlen(cp);;
this->data = new char[length+1];
strcpy_s(
this->data,length+1,cp);
}
void String_ref::release()
{
delete []
this->data;
this->data = NULL;
}
const char* String_ref::getData()const
{
return this->data;
}
//////////////////////////////////////
// String实现区
//////////////////////////////////////
String::String(const char* cp):proxy(new String_ref(cp))
{
proxy
->AddRef();
}
String::
~String()
{
proxy
->DecRef();
}
String::String(
const String& s):proxy(s.proxy)
{
proxy
->AddRef();
}
const String& String::operator = (const String& s)
{
if(&s!=this)
{
proxy
->DecRef();
proxy
= s.proxy;
proxy
->AddRef();
}
return *this;
}
void String::ToLower()
{
//写时复制
if(this->proxy->count>1)
{
//还有其他的持有者,进行"写时复制"
String_ref* new_ref = new String_ref(this->proxy->data);//创建新的字符串内部代理对象,拷贝当前字符串到新创建对象
this->proxy->DecRef();//退出原来的
this->proxy = new_ref;
this->proxy->AddRef();//进入新创建的
}
assert(proxy
->count==1);//验证自己是创建者
//小写化
for(char* cp=proxy->data;*cp;++cp)
{
*cp = tolower(*cp);
}
}
char String::operator[] (int index)const
{
return (*proxy)[index];
}
int String::Length()const
{
return proxy->Length();
}
ostream
& operator << (ostream& out,const String& rhs)
{
out<<rhs.proxy->getData()<<endl;
return out;
}

Code
<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->//////////////////////////////////////
// String_ref类声明
//////////////////////////////////////

#include
"String.h"

class String_ref
{
private:
friend
class String;//友元类
int count;//引用计数
char* data;//数据域
public:
String_ref(
const char*);
String_ref(
const String_ref&);
~String_ref();
const String_ref& operator = (const String_ref&);
char operator[](int)const;
int Length()const;

void AddRef();//引用计数加1
void DecRef();//引用计数减1
const char* getData()const;
private:
void init(const char*);
void release();
};

测试代码:

<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->#include"String.h"
intmain()
{
Strings1(
"HelloWorld");
Strings2(s1);
Strings3;
s3
=s1;
cout
<<s1<<s2<<s3;
s1.ToLower();
cout
<<s1<<s2<<s3;
cout
<<s1[0]<<endl;
cout
<<s1.Length()<<endl;
system(
"pause");
return0;
}



分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics