C++—string类写实拷贝的实现

>1.本次实现string为写实拷贝版本,参照new[]的形式,我们每次实现申请空间时,多在前面开辟4个字节来存放我们的引用计数,所谓的引用计数就是记录当前空间有多少对象在使用。也就是浅拷贝的形式。

>2.为了完善string的实现,我们在不进行修改当前空间时,多个对象可以对公用的空间读取,我们采用浅拷贝的形式对这块空间管理,引用计数的值代表当前空间有多少对象在使用,没有一个对象交出主动权,引用计数减少一个,每当有一个空间对其管理,引用计数增加一个。

>3.当我们所需要的对象对这块空间进行写操作的时候,我们需要进行深拷贝,为此对象单独开辟自己的空间来完成写入操作。

>4.此次的模拟实现没有考虑到多线程的场景,在必要的使用是,多个对象对一块空间进行管理的时候,我们需要的是进行加锁操作,来保证数据不会出错。

>5.对Checkreallocate()函数进行封装,来检测当进行写入操作时,当前空间需不要重新开辟。

这里写图片描述

#include<iostream>
#include<assert.h>
#include<string>
using namespace std;

class String
{
public:
    String(const char* ptr = "")
        :_size(strlen(ptr))
    {
        _capacity = _size;
        _str = new char[_size + 5];
        *(int*)_str = 1;
        strcpy((_str + 4), ptr);
    }

    String(const String& s)
        :_str(s._str)
        , _size(s._size)
        , _capacity(s._capacity)
    {

        (*(int*)_str)++;
    }

    String& operator=(const String& s)
    {
        if (_str != s._str)
        {
            release();
            _str = s._str;
            (*(int*)_str)++;
            _size = s._size;
            _capacity = s._capacity;
        }
        return *this;
    }

    ~String()
    {
        release();
    }

    void release()
    {
        if (--(*(int*)_str) == 0)
        {
            (char*)_str;
            delete[] _str;
            _str = NULL;
        }
    }

    void Checkreallocate()
    {
        if (*(int*)_str>1)
        {
            (*(int*)_str)--;
            char* tmp = new char[_capacity + 5];
            *(int*)tmp = 1;
            strcpy((tmp - 4), (_str-4));
            _str = tmp;
        }
    }

    void Insert(size_t pos, char s)
    {
        assert(pos<_size);
        if (_size == _capacity)
        {
            Expand(_capacity * 2);
        }
        size_t end = _size;
        while (end >= pos)
        {
            (_str + 4)[end + 1] = (_str + 4)[end];
            end--;
        }
        (_str + 4)[pos] = s;
        _size++;
    }

    void Insert(size_t pos, const char* str)
    {
        size_t len = strlen(str);
        Expand(len + _size);
        size_t end = _size;
        while (end >= pos)
        {
            (_str + 4)[end + len] = (_str + 4)[end];
            end--;
        }
        size_t index = 0;
        while (len>index)
        {
            (_str + 4)[pos + index] = str[index];
            index++;
            len--;
        }
        _size += len;
    }

    void Append(const char* str)
    {
        Insert(_size, str);
    }

    void Swap(String& s)
    {
        Checkreallocate();
        swap(_str, s._str);
        swap(_size, s._size);
        swap(_capacity, s._capacity);
    }

    void Expand(size_t n)
    {
        if (n>_capacity)
        {
            if (*(int*)_str>1)
            {
                *(int*)_str--;
            }
            char* tmp = new char[n + 5];
            _capacity = n;
            *(int*)_str = 1;
            strcpy((tmp - 4), _str);
            _str = tmp;
        }
    }

    char& operator[](size_t pos)
    {
        assert(pos<_size);
        Checkreallocate();
        return (_str + 4)[pos];
    }

    String operator+(const String& s)
    {
        String tmp(*this);
        tmp.Insert(_size, (s._str + 4));
        return tmp;
    }

    String& operator+=(const String& s)
    {
        Checkreallocate();
        Insert( _size,(s._str+4));
        return *this;
    }

    void Erase(size_t pos, size_t n)
    {
        assert(pos<_size);
        Checkreallocate();
        if (pos + n<_size)
        {
            size_t index = pos;
            while (index + n <= _size)
            {
                (_str + 4)[index] = (_str + 4)[index + n];
                index++;
            }
        }
        else
        {
            (_str + 4)[pos] = 0;
        }
        _size -= n;
    }

    void PushBack(char s)
    {
        Insert(_size, s);
    }

    void PopBack()
    {
        assert(_size>0);
        Erase(_size - 1, 1);
    }

    bool operator<(const String& s)
    {
        char* str1 = (_str + 4);
        char* str2 = (_str + 4);
        while (*str1&&*str2)
        {
            if (*str1<*str2)
                return true;
            else if (*str1>*str2)
                return false;
            else
            {
                str1++;
                str2++;
            }
        }
        if (*str2 == '/0')
            return false;
        else
            return true;
    }

    bool operator<=(const String& s)
    {
        char* str1 = (_str + 4);
        char* str2 = (_str + 4);
        while (*str1&&*str2)
        {
            if (*str1<*str2)
                return true;
            else if (*str1>*str2)
                return false;
            else
            {
                str1++;
                str2++;
            }
        }
        if (*str1 == *str2)
            return true;
        else
            return false;
    }

    bool operator>(const string& s)
    {
        char* str1 = (_str + 4);
        char* str2 = (_str + 4);
        while (*str1&&*str2)
        {
            if (*str1>*str2)
                return true;
            else if (*str1<*str2)
                return false;
            else
            {
                str1++;
                str2++;
            }
        }
        if (*str1 == '/0')
            return false;
        else
            return true;
    }

    bool operator>=(const String& s)
    {
        char* str1 = (_str + 4);
        char* str2 = (_str + 4);
        while (*str1&&*str2)
        {
            if (*str1>*str2)
                return true;
            else if (*str1<*str2)
                return false;
            else
            {
                str1++;
                str2++;
            }
        }
        if (*str1 == *str2)
            return true;
        else
            return false;
    }

    bool operator==(const String& s)
    {
        char* str1 = (_str + 4);
        char* str2 = (_str + 4);
        while (*str1++ == *str2++)
        {
            if (*(--str1) == '/0')
                return true;
        }
        return false;
    }

    bool operator!=(const String& s)
    {
        return !(operator==(s));
    }

    char* C_str()
    {
        Checkreallocate();
        return (_str + 4);
    }

    void Print()
    {
        cout << (_str + 4) << endl;
    }
private:
    char* _str;
    size_t _size;
    size_t _capacity;
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值