引用计数的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;
}
标签:src,string,计数,int,char,String,mpstr,拷贝,写时 来源: https://blog.csdn.net/KingOfMyHeart/article/details/90343917