写时拷贝的方式实现基本的String类

写时拷贝copy_on_write的方式实现基本的String类,从字面意思来讲就是在需要修改字符串的时候将其拷贝一份,然后进行修改。这里引入了引用计数的概念,在写时拷贝时我们需要注意以下几个问题:

1.开始开辟空间时会多开辟4个字节,是引用计数存放的空间,数据从4个字节以后开始存放;

2.在进行重新写入时,如果引用计数为1那么只需要修改即可,不用再进行拷贝;如果引用计数大于1,在修改时才需要重新拷贝一份;

3.再释放空间时,千万要记得连引用计数那块4个字节的空间一起delete.

下面给出用写时拷贝的方式实现基本String类的代码:

#include<iostream>
#include<cstring>
#include<assert.h>
using namespace std;
class String
{
	friend ostream& operator<<(ostream& os,const String& s);
public:
	String(const char* str=""):_str(new char[strlen(str)+1+4])
	{
		_str=_str+4;    //找到数据存放的地方(数组前面4个字节是引用计数的空间)
		GetCount()=1;
		strcpy(_str,str);
	}
	String(const String& s):_str(s._str)
	{
		++GetCount();
	}
	~String()
	{
		if(--GetCount()==0)
		{
			delete[] (_str-4);   //连存放引用计数那块空间一起释放
		}
	}
	String& operator=(String& s)
	{
		if(this!=&s)
		{
			if(--GetCount()==0)
			{
				delete[] (_str-4);
			}
			++s.GetCount();
			_str=s._str;
		}
		return *this;
	}
	char& operator[](int index)
	{
		assert(index>=0);   //表达式为真,继续执行下面的
		assert(index<(int)strlen(_str));
		if(GetCount()>1)
		{
			--GetCount();
			char* tmp=new char[strlen(_str)+1+4]; //tmp临时变量,出作用域自行销毁
			strcpy(tmp+4,_str);
			_str=tmp+4;
			GetCount()=1;
		}
		return _str[index];
	}
private:
	char* _str;
	int& GetCount()         //引用计数
	{
		return *((int*)_str-1);
	}
};
ostream& operator<<(ostream& os,const String& s)
{
	os<<s._str<<endl;
	return os;
}
void test1()
{
	String s1("hello world");
	String s2(s1);
	String s3;
	s3=s1;
	cout<<s1<<endl;
	cout<<s2<<endl;
	cout<<s3<<endl;
}
void test2()
{
	String s1("work");
	s1[3]='d';
	cout<<s1<<endl;
}
int main()
{
	test2();
	system("pause");
	return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值