引用计数的string(写时拷贝)

#include<iostream>
using namespace std;

//只有要改写对应的字符串时才给重新分配空间,否则它们指向同一个字符串空间
//开辟字符串的时候,给他多开辟四字节的空间,前四个字节增加一个引用计数,初始化为1表示本身的引用计数
//每浅拷贝一次,都给引用计数加1,直到需要修改字符串的内容,才给引用计数-1  然后重新开辟内存,同样多开辟四字节的内容,
//用来记录引用计数,避免了空间中存在同一个字符串的多份副本

//不是线程安全的    线程安全:对引用计数进行CAS
class String
{
public:
String(char *ptr = NULL)
{
	if (ptr != NULL)
	{
		mpstr = new char[strlen(ptr) + 1 + 4];
		strcpy(mpstr + 4, ptr);
	}
	else
	{
		mpstr = new char[1 + 4];
		mpstr[4] = '\0';
	}
	*((int*)mpstr) = 1;
}
String(const String &src)//浅拷贝
{
	mpstr = src.mpstr;
	++(*((int*)mpstr));	
}
String& operator=(const String &src)
{
	if (this != &src)
	{
		if ((*((int *)mpstr)) == 0)
		{
			delete[](mpstr - 4);
		}
		mpstr = src.mpstr;
		++(*((int *)mpstr));
	}
	return *this;
}
~String()
{
	(*((int *)mpstr))--;
	if (*((int *)mpstr) == 0)
	{
		delete[]mpstr;
		mpstr = NULL;
	}
}

bool operator>(const String &src)
{
	return strcmp(mpstr, src.mpstr) > 0;
}
bool operator<(const String &src)
{
	return strcmp(mpstr, src.mpstr) < 0;
}
bool operator==(const String &src)
{
	return strcmp(mpstr, src.mpstr) == 0;
}

size_t length()const
{
	return strlen(this->mpstr + 4);
}

char& operator[](int index) //返回对应下标的字符    //写时拷贝
{
	if ((*((int*)mpstr)) > 1)
	{
		--(*((int*)mpstr));
		char *tmp = new char[strlen(mpstr) + 1];
		strcpy(tmp + 4, mpstr);
		*((int*)tmp) = 1;
		mpstr = tmp + 4;
	}
	index += 4;
	return mpstr[index];
}

const char* c_str()const { return (this->mpstr + 4); }
private:
	mutable char *mpstr;  //常方法中   需要将mpstr+4再求其长度

	friend ostream& operator<<(ostream &out, const String &src);
	friend String operator+(const String &lhs, const String &rhs);
	friend ostream& operator<<(ostream &out, const String &src);
};
ostream& operator<<(ostream &out, const String &src)
{

	out << src.mpstr + 4;
	return out;
}
//operator+
//处理这个方法的内存泄露问题
String operator+(const String &lhs, const String &rhs)
{

	//char * ptr = new char[strlen(lhs.mpstr+4) + strlen(rhs.mpstr+4) + 1];
	char *ptr = new char[lhs.length() + rhs.length() + 1];
	cout << "strlen ptr:      " << strlen(ptr) << endl;
	strcpy(ptr, lhs.mpstr + 4);
	strcat(ptr, rhs.mpstr + 4);
	cout << "ptr  is   " << ptr << endl;
	String tmp(ptr);

	return tmp;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值