C++实现引用计数的string

结尾有代码

因为是引用计数(References counting),所以我起名为RCstring

首先是要包含的头文件

#include <string>
#include <unordered_map>

unordered_map能以O(1)的时间复杂度查找,插入,删除,用来保存所有字符串对象最合适

要用一个哈希表用来存放我门的数据,要先确认一下key和value是什么

先说一下我踩的坑,原本我用的是char*,但千不该万不该忘了char*和char*比较是比的地址

导致每次在哈希表中查询都找不到对应的value

被自己的愚蠢击败...

其实也可以重载一下,改变它的比较方式,但实在没有必要

最简单的办法就是key设置成std::string

为了方便管理这些资源,需要一个类保护这些数据

    class RCstringValue
    {
        void copy_str(const char* rhs);
    public:
        char* value;
        int realsize;
        int count;
        RCstringValue();
        RCstringValue(RCstringValue* rhs);
        ~RCstringValue();
        friend RCstring;
    };

value就是保存的字符串

realsize用于保存value的真实长度

count用于保存指向这个指针的数量

copy_str是一个私有函数,用来复制rhs的数据

void RCstring::RCstringValue::copy_str(const char* rhs)
{
    realsize = strlen(rhs);
    value = new char[realsize] {};
    for (int i = 0; i < realsize; ++i)
    {
        value[i] = rhs[i];
    }
    count = 1;
}
RCstring::RCstringValue::RCstringValue()
    :value(nullptr), realsize(0), count(0)
{

}
RCstring::RCstringValue::RCstringValue(RCstringValue* rhs)
{
    copy_str(rhs->value);
}
RCstring::RCstringValue::~RCstringValue()
{
    delete[]value;
    value = nullptr;
}

不要疑惑为什么析构函数直接清理,因为我们不使用普通变量,而是使用指针

真正的析构放在RCstring的析构函数里

    RCstringValue* value;
    bool locked;
    int Size;
    void copy();
    void point_to(const RCstring& rcstr);
    static std::unordered_map<std::string, RCstringValue*> hash;

私有成员

Size表示使用的大小,而realsize表示的是真实大小,是不一样的

copy用来复制自身

point_to用来指向另一个对象

hash就是储存所有RCstringValue的地址

用value中的value可以得到对应的key,相同的值使用相同的key,从而指向一个对象

//无参
RCstring::RCstring()
    :value(nullptr), locked(false), Size(0)
{

}
//确认长度的构造函数
RCstring::RCstring(int length)
    :locked(false)
{
    value = new RCstringValue();
    value->value = new char[length];
    value->count = 1;
    value->realsize = length;
    Size = 0;
}
RCstring::RCstring(const char* rhs)
    :locked(false)
{
    auto iter = hash.find(rhs);
    //如果在hash里找到rhs对应的value
    if (iter != hash.end())
    {
        //指向
        value = iter->second;
        Size = value->realsize;
        //增加计数器
        ++value->count;
    }
    else
    {
        //新建对象
        value = new RCstringValue();
        value->copy_str(rhs);
        Size = value->realsize;
        hash.insert(std::pair<std::string, RCstringValue*>(rhs, value));
    }
}
RCstring::RCstring(const std::string& rhs)
    :RCstring(rhs.data())
{

}
RCstring::RCstring(const RCstring& rhs)
    :locked(false)
{
    if (rhs.locked)
    {
        value = new RCstringValue();
        value->copy_str(rhs.value->value);
        Size = value->realsize;
        hash.insert(std::pair<std::string, RCstringValue*>(rhs.value->value, value));
    }
    else
    {
        value = rhs.value;
        Size = rhs.value->realsize;
        ++value->count;
    }

}

locked用来表达是否有指针指向它

如果没有,locked为false,可以正常用指向它的值

如果有,locked为true,表达它有可能被修改,新建一份对象

当然凭借我的实力是做不出每时每刻跟随的效果的,但是只要手动处理一下就可以,非常简单

void RCstring::copy()
{
    value = new RCstringValue(value);
}
void RCstring::point_to(const RCstring& rcstr)
{
    this->~RCstring();
    value = rcstr.value;
    ++value->count;
}
RCstring::~RCstring()
{
    --value->count;
    if (value->count == 0)
    {
        hash.erase(value->value);
        delete value;
        value = nullptr;
    }
}

接下来是两个很重要的函数

void RCstring::lock()
{
    locked = true;
    if (value->count > 1)
    {
        copy();
    }
}
void RCstring::unlock()
{
    if (!locked)
    {
        return;
    }
    auto iter = hash.find(value->value);
    locked = false;
    if (iter != hash.end())
    {
        delete value;
        value = iter->second;
        ++value->count;
    }
    else
    {
        hash.insert(std::pair<std::string, RCstringValue*>(value->value, value));
    }
}

lock判断一下当前指向value的数量,如果只有一个的话就什么也不做

否则就复制一次自身,从引用计数系统里移除

unlock判断一下value对应的value是否存在,如果存在则不需要这个value,释放后指向引用计数系统的value,而不存在则插入这个value,重新加入引用计数系统

这样就可以做到在频繁修改时先退出引用计数系统,而在修改完毕后再次加入的效果

目前来看需要手动lock的情况基本不存在,只需要手动unlock就可以了

char& RCstring::operator[](int index)
{
    if (locked)
    {
        return value->value[index];
    }
    lock();
    return value->value[index];
}
char RCstring::operator[](int index)const
{
    return value->value[index];
}
char RCstring::operator()(int index)const
{
    return value->value[index];
}
char RCstring::at(int index)const
{
    if (index < 0 || index>Size)
    {
        std::abort();
    }
    return value->value[index];
}

这四个都是返回index的字符

第一个是修改的时候才需要使用的,如果没有手动lock就会自动lock

第二个是用于常量对象的,返回值不是引用,无法修改值

第三个是我用来方便非常量对象读取用的,不会修改值

第四个是std::string里也有的,它会判断一下下标是否非法

然后就可以实现各种成员函数了

RCstring RCstring::substr(int start, int length)const
{
    RCstring rc(length);
    rc.Size = length;
    rc.lock();
    for (int i = start; i < start + length; ++i)
    {
        rc[i - start] = value->value[i];
    }

    rc.unlock();
    return rc;
}

一般来说rc是不需要手动lock的,但是用来提醒自己非常合适

其它的就很简单了

void RCstring::assign(int num, char ch)
{
    RCstring rcstr(num);
    rcstr.lock();
    for (int i = 0; i < num; ++i)
    {
        rcstr[i] = ch;
    }
    rcstr.unlock();
    Size = num;
    point_to(rcstr);
}
void RCstring::append(const std::string& str)
{
    if (Size + str.size() > value->realsize)
    {
        RCstring rcstr = Size + str.size();
        rcstr.lock();
        for (int i = 0; i < Size; ++i)
        {
            rcstr[i] = value->value[i];
        }
        for (int i = Size; i < Size + str.size(); ++i)
        {
            rcstr[i] = str[i - Size];
        }
        rcstr.unlock();
        Size = Size + str.size();
        point_to(rcstr);
        return;
    }
    lock();
    for (int i = Size; i < Size + str.size(); ++i)
    {
        value->value[i] = str[i - Size];
    }
    unlock();
    Size = Size + str.size();
}
void RCstring::erase(int start, int length)
{
    RCstring rcstr(value->realsize - length);
    rcstr.lock();
    bool isturned = false;
    for (int i = 0; i < value->realsize; ++i)
    {
        if (i == start)
        {
            i += length;
            isturned = true;
        }
        if (i < value->realsize)
        {
            if (!isturned)
            {
                rcstr[i] = value->value[i];
            }
            else
            {
                rcstr[i - length] = value->value[i];
            }
        }
    }
    rcstr.unlock();
    Size -= length;
    point_to(rcstr);
}
void RCstring::resize(int Newsize, char ch)
{
    if (Newsize < Size)
    {
        Size = Newsize;
        return;
    }
    RCstring rcstr(Newsize);
    rcstr.lock();
    for (int i = 0; i < Size; ++i)
    {
        rcstr[i] = value->value[i];
    }
    for (int i = Size; i < Newsize; ++i)
    {
        rcstr[i] = ch;
    }
    rcstr.unlock();
    Size = Newsize;
    point_to(rcstr);
}
void RCstring::reverse(int Newsize)
{
    if (Newsize < Size)
    {
        return;
    }
    RCstring rcstr(Newsize);
    rcstr.lock();
    for (int i = 0; i < Size; ++i)
    {
        rcstr[i] = value->value[i];
    }
    rcstr.unlock();
    point_to(rcstr);
}
void RCstring::insert(int Where, const char* ptr)
{
    int length = strlen(ptr);
    if (Size + length > value->realsize)
    {
        RCstring rcstr = Size + length;
        rcstr.lock();
        int n = 0;
        for (int i = 0; i < Size + length; ++i)
        {
            if (i == Where)
            {
                int z = 0;
                for (int u = i; u < i + length; ++u)
                {
                    rcstr[u] = ptr[z];
                    ++z;
                }
                n = length;
            }
            rcstr[i + n] = value->value[i];
        }
        rcstr.unlock();
        Size += length;
        point_to(rcstr);
        return;
    }
    for (int right = Size + length - 1; right > Where; --right)
    {
        std::swap(value->value[right], value->value[right - 1]);
    }
    for (int i = Where; i < Where + length; ++i)
    {
        value->value[i] = ptr[i - Where];
    }
    Size += length;
}
const RCstring RCstring::operator+(const char* ptr)
{
    int length = strlen(ptr);
    RCstring str = length + Size;
    str.lock();
    for (int i = 0; i < Size; ++i)
    {
        str[i] = value->value[i];
    }
    for (int i = Size; i < Size + length; ++i)
    {
        str[i] = ptr[i - Size];
    }
    str.unlock();
    str.Size = length + Size;
    return str;
}

有一点要注意,这也是我踩过的坑,虽然写了参数为const char* 的函数,但是不能直接append(str.data()),因为如果这么做是把整个指针都复制过去,但我们使用的可能不是整个指针而是其中的一部分,这也是我为什么要把Size分发到各个RCstring里而不是加入引用计数系统

比如一个字符串 aabbccddee

有个RCstring的RCstringValue指向它

如果它想让它的Size变为2,只需要一个赋值就可以了,但是如果Size放在RCstringValue里就要新建一个对象,而它们的区别就是使用的大小不同而已

最后附上源码

#include <string>
#include<unordered_map>
class RCstring
{
    class RCstringValue
    {
        void copy_str(const char* rhs);
    public:
        char* value;
        int realsize;
        int count;
        RCstringValue();
        RCstringValue(RCstringValue* rhs);
        ~RCstringValue();
        friend RCstring;
    };
    class iterator
    {
        char* value;
    public:
        iterator(char* p);
        iterator operator++();
        iterator operator++(int);
        iterator operator--();
        iterator operator--(int);
        iterator operator+(int val);
        iterator operator-(int val);
        char operator*();
        bool operator==(iterator another);
        bool operator!=(iterator another);
    };
    RCstringValue* value;
    bool locked;
    int Size;
    void copy();
    void point_to(const RCstring& rcstr);
    static std::unordered_map<std::string, RCstringValue*> hash;
public:
    RCstring();
    RCstring(int length);
    RCstring(const char* rhs);
    RCstring(const std::string& rhs);
    RCstring(const RCstring& rhs);
    RCstring substr(int start, int length)const;
    std::vector<RCstring> split(char p)const;
    void assign(int num, char ch);
    void assign(const char* ptr);
    void assign(const RCstring& s);
    void assign(const std::string& s);
    void assign(iterator start, iterator end);
    void append(const std::string& str);
    void append(const RCstring& str);
    void append(const char* ptr);
    void append(iterator start, iterator end);
    void erase(int off);
    void erase(int start, int length);
    void erase(iterator off);
    void erase(iterator start, iterator end);
    void resize(int NewSize, char Ch = 0);
    void reverse(int Newsize);
    void insert(int Where, char p);
    void insert(int Where, const char* ptr);
    void insert(int Where, const std::string& str);
    void insert(int Where, const RCstring& str);
    const RCstring operator+(const RCstring& rhs);
    const RCstring operator+(const char* rhs);
    const RCstring operator+(const std::string& rhs);
    iterator begin()const;
    iterator end()const;
    iterator rbegin()const;
    iterator rend()const;
    const char* data()const;
    int toint()const;
    float tofloat()const;
    std::string tostring()const;
    void lock();
    void unlock();
    RCstring& operator=(const RCstring& rhs);
    bool operator==(const RCstring& rhs);
    bool operator!=(const RCstring& rhs);
    char& operator[](int index);
    char operator[](int index)const;
    char operator()(int index)const;
    char at(int index)const;
    int size()const;
    int max_size()const;
    ~RCstring();
};
std::unordered_map<std::string, RCstring::RCstringValue*> RCstring::hash;
void RCstring::RCstringValue::copy_str(const char* rhs)
{
    realsize = strlen(rhs);
    value = new char[realsize] {};
    for (int i = 0; i < realsize; ++i)
    {
        value[i] = rhs[i];
    }
    count = 1;
}
RCstring::RCstringValue::RCstringValue()
    :value(nullptr), realsize(0), count(0)
{

}
RCstring::RCstringValue::RCstringValue(RCstringValue* rhs)
{
    copy_str(rhs->value);
}
RCstring::RCstringValue::~RCstringValue()
{
    delete[]value;
    value = nullptr;
}
RCstring::iterator::iterator(char* p)
{
    value = p;
}
RCstring::iterator RCstring::iterator::operator++()
{
    return ++value;
}
RCstring::iterator RCstring::iterator::operator++(int)
{
    iterator iter = *this;
    ++value;
    return iter;
}
RCstring::iterator RCstring::iterator::operator--()
{
    return --value;
}
RCstring::iterator RCstring::iterator::operator--(int)
{
    iterator iter = *this;
    --value;
    return iter;
}
RCstring::iterator RCstring::iterator::operator+(int val)
{
    return value + val;
}
RCstring::iterator RCstring::iterator::operator-(int val)
{
    return value - val;
}
char RCstring::iterator::operator*()
{
    return *value;
}
bool RCstring::iterator::operator==(RCstring::iterator another)
{
    return value == another.value;
}
bool RCstring::iterator::operator!=(RCstring::iterator another)
{
    return value != another.value;
}
void RCstring::copy()
{
    value = new RCstringValue(value);
}
void RCstring::point_to(const RCstring& rcstr)
{
    this->~RCstring();
    value = rcstr.value;
    ++value->count;
}
RCstring::RCstring()
    :value(nullptr), locked(false), Size(0)
{

}
RCstring::RCstring(int length)
    :locked(false)
{
    value = new RCstringValue();
    value->value = new char[length];
    value->count = 1;
    value->realsize = length;
    Size = 0;
}
RCstring::RCstring(const char* rhs)
    :locked(false)
{
    auto iter = hash.find(rhs);
    if (iter != hash.end())
    {
        value = iter->second;
        Size = value->realsize;
        ++value->count;
    }
    else
    {
        value = new RCstringValue();
        value->copy_str(rhs);
        Size = value->realsize;
        hash.insert(std::pair<std::string, RCstringValue*>(rhs, value));
    }
}
RCstring::RCstring(const std::string& rhs)
    :RCstring(rhs.data())
{

}
RCstring::RCstring(const RCstring& rhs)
    :locked(false)
{
    if (rhs.locked)
    {
        value = new RCstringValue();
        value->copy_str(rhs.value->value);
        Size = value->realsize;
        hash.insert(std::pair<std::string, RCstringValue*>(rhs.value->value, value));
    }
    else
    {
        value = rhs.value;
        Size = rhs.value->realsize;
        ++value->count;
    }

}
RCstring RCstring::substr(int start, int length)const
{
    RCstring rc(length);
    rc.Size = length;
    rc.lock();
    for (int i = start; i < start + length; ++i)
    {
        rc[i - start] = value->value[i];
    }

    rc.unlock();
    return rc;
}
std::vector<RCstring> RCstring::split(char p)const
{
    std::vector<RCstring> v;
    int slow = 0;
    int n = size();
    for (int fast = 0; fast < n; ++fast)
    {
        if (value->value[fast] == p)
        {
            if (fast != 0)
            {
                if (value->value[fast - 1] != p)
                {
                    RCstring str = substr(slow, fast - slow);
                    ++str.value->count;
                    v.push_back(str);
                    slow = fast + 1;
                }
                else
                {
                    ++slow;
                }
            }
            else
            {
                ++slow;
            }
        }
        else if (fast == n - 1)
        {
            RCstring str = substr(slow, fast - slow);
            ++str.value->count;
            v.push_back(str);
        }
    }
    return v;

}
void RCstring::assign(int num, char ch)
{
    RCstring rcstr(num);
    rcstr.lock();
    for (int i = 0; i < num; ++i)
    {
        rcstr[i] = ch;
    }
    rcstr.unlock();
    Size = num;
    point_to(rcstr);
}
void RCstring::assign(const char* ptr)
{
    RCstring rcstr(strlen(ptr));
    rcstr.lock();
    rcstr.value->copy_str(ptr);
    rcstr.unlock();
    Size = rcstr.max_size();
    point_to(rcstr);
}
void RCstring::assign(const RCstring& s)
{
    point_to(s.data());
    Size = s.size();
}
void RCstring::assign(const std::string& s)
{
    point_to(s.data());
    Size = s.size();
}
void RCstring::assign(iterator start, iterator end)
{
    int length = 0;
    for (auto iter = start; iter != end; ++iter)
    {
        ++length;
    }
    RCstring rcstr = length;
    rcstr.lock();
    int i = 0;
    for (auto iter = start; iter != end; ++iter)
    {
        rcstr[i] = *iter;
        ++i;
    }
    Size = length;
    point_to(rcstr);
}
void RCstring::append(const std::string& str)
{
    if (Size + str.size() > value->realsize)
    {
        RCstring rcstr = Size + str.size();
        rcstr.lock();
        for (int i = 0; i < Size; ++i)
        {
            rcstr[i] = value->value[i];
        }
        for (int i = Size; i < Size + str.size(); ++i)
        {
            rcstr[i] = str[i - Size];
        }
        rcstr.unlock();
        Size = Size + str.size();
        point_to(rcstr);
        return;
    }
    lock();
    for (int i = Size; i < Size + str.size(); ++i)
    {
        value->value[i] = str[i - Size];
    }
    unlock();
    Size = Size + str.size();
}
void RCstring::append(const RCstring& str)
{
    if (Size + str.Size > value->realsize)
    {
        RCstring rcstr = Size + str.Size;
        rcstr.lock();
        for (int i = 0; i < Size; ++i)
        {
            rcstr[i] = value->value[i];
        }
        for (int i = Size; i < Size + str.Size; ++i)
        {
            rcstr[i] = str[i - Size];
        }
        rcstr.unlock();
        Size = Size + str.Size;
        point_to(rcstr);
        return;
    }
    lock();
    for (int i = Size; i < Size + str.Size; ++i)
    {
        value->value[i] = str[i - Size];
    }
    unlock();
    Size = Size + str.Size;
}
void RCstring::append(const char* ptr)
{
    int length = strlen(ptr);
    if (Size + length > value->realsize)
    {
        RCstring rcstr = Size + length;
        rcstr.lock();
        for (int i = 0; i < Size; ++i)
        {
            rcstr[i] = value->value[i];
        }
        for (int i = Size; i < Size + length; ++i)
        {
            rcstr[i] = ptr[i - Size];
        }
        rcstr.unlock();
        Size = Size + length;
        point_to(rcstr);
        return;
    }
    lock();
    for (int i = Size; i < Size + length; ++i)
    {
        value->value[i] = ptr[i - Size];
    }
    unlock();
    Size = Size + length;
}
void RCstring::append(iterator start, iterator end)
{
    int length = 0;
    for (auto a = start; a != end; ++a)
    {
        ++length;
    }
    if (Size + length > value->realsize)
    {
        RCstring rcstr = Size + length;
        rcstr.lock();
        for (int i = 0; i < Size; ++i)
        {
            rcstr[i] = value->value[i];
        }
        int i = Size;
        for (auto a = start; a != end; ++a)
        {
            rcstr[i] = *a;
            ++i;
        }
        rcstr.unlock();
        Size = Size + length;
        point_to(rcstr);
        return;
    }
    lock();
    int i = Size;
    for (auto a = start; a != end; ++a)
    {
        value->value[i] = *a;
        ++i;
    }
    unlock();
    Size = Size + length;
}
void RCstring::erase(int off)
{
    Size = off;
}
void RCstring::erase(int start, int length)
{
    RCstring rcstr(value->realsize - length);
    rcstr.lock();
    bool isturned = false;
    for (int i = 0; i < value->realsize; ++i)
    {
        if (i == start)
        {
            i += length;
            isturned = true;
        }
        if (i < value->realsize)
        {
            if (!isturned)
            {
                rcstr[i] = value->value[i];
            }
            else
            {
                rcstr[i - length] = value->value[i];
            }
        }
    }
    rcstr.unlock();
    Size -= length;
    point_to(rcstr);
}
void RCstring::erase(RCstring::iterator off)
{
    int index = 0;
    for (auto a = begin(); a != off; ++a)
    {
        ++index;
    }
    Size = index;
}
void RCstring::erase(iterator _start, iterator _end)
{
    int length = 0;
    for (auto a = _start; a != _end; ++a)
    {
        ++length;
    }
    RCstring rcstr = Size - length;
    rcstr.lock();
    int i = 0;
    for (auto a = begin(); a != end(); ++a)
    {
        if (a == _start)
        {
            a = _end;
        }
        if (a != end())
        {
            rcstr[i] = *a;
            ++i;
        }
    }
    rcstr.unlock();
    Size -= length;
    point_to(rcstr);
}
void RCstring::resize(int Newsize, char ch)
{
    if (Newsize < Size)
    {
        Size = Newsize;
        return;
    }
    RCstring rcstr(Newsize);
    rcstr.lock();
    for (int i = 0; i < Size; ++i)
    {
        rcstr[i] = value->value[i];
    }
    for (int i = Size; i < Newsize; ++i)
    {
        rcstr[i] = ch;
    }
    rcstr.unlock();
    Size = Newsize;
    point_to(rcstr);
}
void RCstring::reverse(int Newsize)
{
    if (Newsize < Size)
    {
        return;
    }
    RCstring rcstr(Newsize);
    rcstr.lock();
    for (int i = 0; i < Size; ++i)
    {
        rcstr[i] = value->value[i];
    }
    rcstr.unlock();
    point_to(rcstr);
}
void RCstring::insert(int Where, char p)
{
    if (Size + 1 > value->realsize)
    {
        RCstring rcstr = Size + 1;
        rcstr.lock();
        int n = 0;
        for (int i = 0; i < Size + 1; ++i)
        {
            if (i == Where)
            {
                rcstr[i] = p;
                n = 1;
            }
            rcstr[i + n] = value->value[i];
        }
        rcstr.unlock();
        ++Size;
        point_to(rcstr);
        return;
    }
    for (int right = Size; right > Where; --right)
    {
        std::swap(value->value[right], value->value[right - 1]);
    }
    value->value[Where] = p;
    ++Size;
}
void RCstring::insert(int Where, const char* ptr)
{
    int length = strlen(ptr);
    if (Size + length > value->realsize)
    {
        RCstring rcstr = Size + length;
        rcstr.lock();
        int n = 0;
        for (int i = 0; i < Size + length; ++i)
        {
            if (i == Where)
            {
                int z = 0;
                for (int u = i; u < i + length; ++u)
                {
                    rcstr[u] = ptr[z];
                    ++z;
                }
                n = length;
            }
            rcstr[i + n] = value->value[i];
        }
        rcstr.unlock();
        Size += length;
        point_to(rcstr);
        return;
    }
    for (int right = Size + length - 1; right > Where; --right)
    {
        std::swap(value->value[right], value->value[right - 1]);
    }
    for (int i = Where; i < Where + length; ++i)
    {
        value->value[i] = ptr[i - Where];
    }
    Size += length;
}
void RCstring::insert(int Where, const std::string& str)
{
    int length = str.size();
    if (Size + length > value->realsize)
    {
        RCstring rcstr = Size + length;
        rcstr.lock();
        int n = 0;
        for (int i = 0; i < Size + length; ++i)
        {
            if (i == Where)
            {
                int z = 0;
                for (int u = i; u < i + length; ++u)
                {
                    rcstr[u] = str[z];
                    ++z;
                }
                n = length;
            }
            rcstr[i + n] = value->value[i];
        }
        rcstr.unlock();
        Size += length;
        point_to(rcstr);
        return;
    }
    for (int right = Size + length - 1; right > Where; --right)
    {
        std::swap(value->value[right], value->value[right - 1]);
    }
    for (int i = Where; i < Where + length; ++i)
    {
        value->value[i] = str[i - Where];
    }
    Size += length;
}
void RCstring::insert(int Where, const RCstring& str)
{
    int length = str.size();
    if (Size + length > value->realsize)
    {
        RCstring rcstr = Size + length;
        rcstr.lock();
        int n = 0;
        for (int i = 0; i < Size + length; ++i)
        {
            if (i == Where)
            {
                int z = 0;
                for (int u = i; u < i + length; ++u)
                {
                    rcstr[u] = str[z];
                    ++z;
                }
                n = length;
            }
            rcstr[i + n] = value->value[i];
        }
        rcstr.unlock();
        Size += length;
        point_to(rcstr);
        return;
    }
    for (int right = Size + length - 1; right > Where; --right)
    {
        std::swap(value->value[right], value->value[right - 1]);
    }
    for (int i = Where; i < Where + length; ++i)
    {
        value->value[i] = str[i - Where];
    }
    Size += length;
}
const RCstring RCstring::operator+(const char* ptr)
{
    int length = strlen(ptr);
    RCstring str = length + Size;
    str.lock();
    for (int i = 0; i < Size; ++i)
    {
        str[i] = value->value[i];
    }
    for (int i = Size; i < Size + length; ++i)
    {
        str[i] = ptr[i - Size];
    }
    str.unlock();
    str.Size = length + Size;
    return str;
}
const RCstring RCstring::operator+(const std::string& str)
{
    RCstring rcstr = Size + str.size();
    rcstr.lock();
    for (int i = 0; i < Size; ++i)
    {
        rcstr[i] = value->value[i];
    }
    for (int i = Size; i < Size + str.size(); ++i)
    {
        rcstr[i] = str[i - Size];
    }
    rcstr.unlock();
    rcstr.Size = Size + str.size();
    return rcstr;
}
const RCstring RCstring::operator+(const RCstring& str)
{
    RCstring rcstr = Size + str.size();
    rcstr.lock();
    for (int i = 0; i < Size; ++i)
    {
        rcstr[i] = value->value[i];
    }
    for (int i = Size; i < Size + str.size(); ++i)
    {
        rcstr[i] = str[i - Size];
    }
    rcstr.unlock();
    rcstr.Size = Size + str.size();
    return rcstr;
}
RCstring::iterator RCstring::begin()const
{
    return value->value;
}
RCstring::iterator RCstring::end()const
{
    return value->value + Size;
}
RCstring::iterator RCstring::rbegin()const
{
    return value->value + Size - 1;
}
RCstring::iterator RCstring::rend()const
{
    return value->value - 1;
}
const char* RCstring::data()const
{
    return value->value;
}
int RCstring::toint()const
{
    return std::stoi(value->value);
}
float RCstring::tofloat()const
{
    return std::stof(value->value);
}
std::string RCstring::tostring()const
{
    return std::string(value->value);
}
void RCstring::lock()
{
    locked = true;
    if (value->count > 1)
    {
        copy();
    }
}
void RCstring::unlock()
{
    if (!locked)
    {
        return;
    }
    auto iter = hash.find(value->value);
    locked = false;
    if (iter != hash.end())
    {
        delete value;
        value = iter->second;
        ++value->count;
    }
    else
    {
        hash.insert(std::pair<std::string, RCstringValue*>(value->value, value));
    }
}
RCstring& RCstring::operator=(const RCstring& rhs)
{
    if (rhs.locked)
    {
        value->copy_str(rhs.value->value);
        Size = value->realsize;
        return *this;
    }
    --value->count;
    if (value->count == 0)
    {
        hash.erase(value->value);
        delete value;
        value = nullptr;
    }
    value = rhs.value;
    ++value->value;
    return *this;
}
bool RCstring::operator==(const RCstring& rhs)
{
    if (Size != rhs.Size)
    {
        return false;
    }
    for (int i = 0; i < Size; ++i)
    {
        if (value->value[i] != rhs[i])
        {
            return false;
        }
    }
    return true;
}
bool RCstring::operator!=(const RCstring& rhs)
{
    if (Size != rhs.Size)
    {
        return true;
    }
    for (int i = 0; i < Size; ++i)
    {
        if (value->value[i] != rhs[i])
        {
            return true;
        }
    }
    return false;
}
char& RCstring::operator[](int index)
{
    if (locked)
    {
        return value->value[index];
    }
    lock();
    return value->value[index];
}
char RCstring::operator[](int index)const
{
    return value->value[index];
}
char RCstring::operator()(int index)const
{
    return value->value[index];
}
char RCstring::at(int index)const
{
    if (index < 0 || index>Size)
    {
        std::abort();
    }
    return value->value[index];
}
int RCstring::size()const
{
    return Size;
}
int RCstring::max_size()const
{
    return value->realsize;
}
RCstring::~RCstring()
{
    --value->count;
    if (value->count == 0)
    {
        hash.erase(value->value);
        delete value;
        value = nullptr;
    }
}

有错误请大佬指正!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值