C++模拟实现string(现代简易深拷贝写法)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/weixin_40921797/article/details/82464537

具体关于string函数写时注意,看注释哦

#include<iostream>
#include<string>
using namespace std;
class String
{
public:
    String(const char* str = "")
        :_str(new char[strlen(str)+1]), 
        _size(strlen(str)),
        _capacity (_size)
    {
    //利用初始化列表,给出一个缺省的构造函数。
        strcpy(_str, str);
    }
    // s1.Swap(s2);两个对象内容交换
    void Swap(String& s)
    {
        swap(this->_str, s._str);
        //swap是库函数
        swap(_size, s._size);
        swap(_capacity, s._capacity);
    }
        // String s2(s1) ;拷贝构造函数
    String(const String& s)
        :_str(NULL),
        _size(strlen(s._str)),
        _capacity(strlen(s._str))
    {
    //我利用一个变量调用构造函数,在和我们要拷贝构造的交换,利用出作用域系统会调用析构,释放tmp
        String tmp(s._str);
        swap(tmp._str, _str);
    }
    // s1 = s2 ;赋值运算符重载
    String& operator=(String s)
    {
    //我利用同样是不需要自己去开空间,调用构造,转变成构造,然后交换的思想
        String tmp(s._str);
        swap(tmp._str, _str);
        _size = tmp._size;
        _capacity = tmp._capacity;
        return *this;
    }
    ~String()
    {
//析构函数
        delete []_str;
        _str = NULL;
        _size = 0;
        _capacity = 0;
    }

    const char* c_str()
    {
        return _str;
    }
    //扩容
    void Expand(size_t n)
    {
        _capacity += n;
        char * tmp = new char[_capacity+1];
        strcpy(tmp, _str);
        swap(tmp, _str);
    }
    //后面添加数据
    void PushBack(char ch)
    {
        if (_size >= _capacity)
        {
            Expand(10);
        }
        _str[_size++] = ch;
        _str[_size] = '\0';
    }
    void PushBack(const char* str)
    {
        if (_size + strlen(str) >= _capacity)
        {
            Expand(strlen(str));
        }
        strcpy((_str + _size), str);
        _size += strlen(str);

    }
    //string 进行的是开空间,但是是不会pop的时候,减空间
    void PopBack()
    {
        _size--;
    }
    //中间插入,我利用的是memmove库函数,来完成占位的后移
    void Insert(size_t pos, char ch)
 {
        if (_size + 1 >= _capacity)
        {
            Expand(10);
        }
        assert(pos >= 0 && pos <= _size);
        memmove(_str + pos+1, _str + pos,_size - pos+1);
        _str[pos] = ch;
        _size++;
    }
    void Insert(size_t pos, const char* str)
    {
        if (_size + strlen(str) >= _capacity)
        {
            Expand(strlen(str));
        }
        assert(pos >= 0 && pos <= _size);
        memmove(_str + pos + strlen(str), _str + pos,_size - pos+1);
        strncpy(_str + pos, str, strlen(str));
        _size += strlen(str);
    }
    //pos位置的删除,我同意利用的库函数,实现前移,然后修改size大小
    void Erase(size_t pos, size_t n = 1)
    {
        assert(pos >= 0 && pos < _size);
        strcpy(_str + pos, _str + pos + 1);
        _size -= 1;
    }
    //查找
    size_t Find(char ch)
    {
        for (int i = 0; i <(int) _size; i++)
        {
            if (_str[i] == ch)
                return i;
        }
        return -1;
    }
     // s1 + 'a' ;+运算符重载+是很浪费空间的,因为在传回时只能传值传回,而+=可以传引用
    String operator+(char ch)
    {
        String tmp(_str);
        tmp.PushBack(ch);
        return tmp;
    }
    //+=运算符重载
    String& operator+=(char ch)
    {
        PushBack(ch);
        return *this;
    }
    String operator+(const char* str)
    {
        String tmp(_str);
        tmp.PushBack(str);
        return tmp;
    }
    String& operator+=(const char* str)
    {
        PushBack(str);
        return *this;
    }
//比较大小的不需要每个都实现,可以复用,只实现几个,其他的利用就好了。
    bool operator>(const String& s)
    {
        if (strcmp(_str, s._str) > 0)
            return true;
        else return false;
    }
    bool operator>=(const String& s)
    {
        return !(*this < s);
    }
    bool operator<(const String& s)
    {
        if (strcmp(_str, s._str) < 0)
            return true;
        else return false;
    }
    bool operator<=(const String& s)
    {
        return !(*this > s);
    }
    bool operator==(const String& s)
    {
        if (strcmp(_str, s._str) == 0)
            return true;
        else return false;
    }
    bool operator!=(const String& s)
    {
        return !(*this == s);
    }
    //输出运算符因为stream需要占用第一个参数,所以不可以写成成员变量,但是又要访问类中私有成员,所以应设为friend友元。
    friend ostream& operator<<(ostream& cout, const String&s);
private:
    char* _str;
    size_t _size;
    size_t _capacity;
};
ostream & operator<<(ostream &cout, const String&s)
{
    cout << s._str;
    return cout;
}

猜你喜欢

转载自blog.csdn.net/weixin_40921797/article/details/82464537