小工具知识网

当前位置: 首页 > 行业知识 > 【C++初阶】string模拟实现

行业知识

【C++初阶】string模拟实现

2026-11-04 03:48:52 来源:互联网转载

✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅

✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨

追风赶月莫停留

平芜尽处是春山

✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨

✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅

string模拟实现

  • 构造函数
  • 析构函数
  • 重载
    • 方括号引用
    • +=操作
    • =操作
    • 迭代器
    • 增删查改
      • 增
      • 找
      • 流提取和流插入

        构造函数

        //有参构造string(char* str){size_t _size = strlen(str);_capacity = _size;str = new char[_capacity+1];strcpy(_str, str);}//无参构造string(){_str = new char[1];_size = 0;_capacity = 0;_str[0] = '
        string (const char* str = "

        析构函数

        "){size_t _size = strlen(str);_capacity = _size;_str = new char[_capacity+1];strcpy(_str, str);}
        ';}

        至于无参构造中,为了防止解引用发生错误,所以特有开了一个空间,并赋值为斜杠0。

        上面代码就是普通的构造函数的写法,无参和有参构造,这里我们并不采用初始化列表的方式进行初始化。

        但实际我们并不会这么写,会直接写一个全缺省:

        ~string(){delete[] _str;_str = nullptr;_size = _capacity = 0;}

        上面中初始化时并不能直接赋值给’\0’,str是字符串类型而’\0’是字符,两者类型不一样,所以应赋值"\0"。当然也可以不用赋值,直接空字符串也是,因为常量字符串中自带斜杠0。

        重载

        方括号引用

        析构函数就没有什么特别需要注意的了,和常规写法差不多

        char& operator[](size_t pos){assert(pos push_back(str);return *this;}string& operator+=(const char* str){append(str);return *this;}if(_str != &s){char* tem = new char[s._capacity+1];strcpy(tem, s._str);delete[] _str;_str = tem;_size = s._size;_capacity = s._capacity;}return *this;}return _str;}iterator end(){return _str + _size;}if (n  _capacity){char* cur = new char[n+1];strcpy(cur, _str);delete[] _str;_str = cur;_capacity = n;}}

        增

        void push_back(char ch){if (_size == _capacity){size_t newcapacity = _capacity == 0 ? 4 : _capacity * 2;reserve(newcapacity);}_str[_size] = ch;_size++;_str[_size] = '
        void append(const char* str){size_t len = strlen(str);if (_size+len > _capacity){reserve(_size+len);}strcpy(_str+_size, str);_size += len;}
        ';}

        这是一个扩容函数,在push_back或insert时,空间都有可能满,所以会先进行扩容。

        void insert(size_t pos, char str){assert(pos size_t newcapacity = _capacity == 0 ? 4 : _capacity * 2;reserve(newcapacity);}size_t end = _size ;while (end = pos){_str[end + 1] = str[end];end--;}_str[pos] = str;_size++;}
        void insert(size_t pos, char* str){size_t len = strlen(str);if (_size + len > _capacity){reserve(_size + len);}size_t end = _size;while (end >= pos){_str[end + len] = _str[end];end--;}strncpy(_str+pos, str, len);_size += len;}

        push_back()函数是在原本string中最后面的位置添加一个字符。

        找

        append()函数和push_back()函数还是有点大径相同,只不过append()是增加一个字符串在原string类后面,不过有一些细节还是需要注意。

        size_t Find(const char* str, size_t pos = 0){const char* ptr = strstr(_str+pos,  str);if (ptr == nullptr){return npos;}else{return ptr - _str;}}

        insert()函数是一个可以在容器内插入字符的函数,在进行插入的时候都要对容器内的空间进行检查,防止空间满。在这里还要注意一点,我们是利用了end来当做循环条件,而end的类型是size_t ,而size_t是无符号整型。

        而当pos为0时,这个时候循环结束条件就是end=-1,但end是size_t 类型,所以当end=-1时,实际上并不会得到你所期望的负数结果。由于size_t是一个无符号整形,所以它会将-1解释为一个非常大的正数。

        所以这种情况下,程序就会陷入***循环。

        string(const string& s){_str = new char[s._capacity+1];strcpy(_str, s._str);_size = s._size;_capacity = s._capacity; }

        该insert()函数和上面的insert()函数功能差不多,但是这里insert()是插入一段字符,而上面的insert()函数是插入一个字符。

        这里最后不能用strcpy(),因为strcpy()会把斜杠0一起复制过去,这样就会覆盖原有的一个值。

        流提取和流插入

        size_t Find(char ch, size_t pos = 0){for(size_t i = pos; i  

        Find()函数是查找某个元素,并返回下标值,npos是全局静态变量,它值为-1, 在这里我们给了pos默认值,默认是从0开始找,也可以指定从那个数开始找。

        ostream& operatorfor (auto ch : s){out _size = 0;_str[0] = '';}istream& operator(istream& in, string& s){s.clear();char ch = in.get();while(ch != ' ' && ch != '\n'){s += ch;ch = in.get();}return in}_size = 0;_str[0] = '';}istream& operator>(istream& in, string& s){s.clear();char open[128] = {0};char ch = in.get();while(ch != ' ' && ch != '\n'){open[i++] = ch;if (i == 127){open[i] = '';s += open;i = 0;}ch = in.get();}if (i > 0){open[i] = '';s += ch;}return in;}

        该函数是查找一段字符串的函数,并返回该字符串的起始位置,npos是全局静态变量,值为-1;

        string substr(size_t pos, size_t len = npos){assert(pos  _size){end = _size;}string str;for (size_t i = pos; i  

        substr()函数从主容器中取出指定范围的数据,其中npos是在上面已经提到过了,而在这len也是size_t类型,上面说过size_t是无符号整型,一旦len为负数,系统就会理解len是一个很大的值,也就相当于要取出的数大于pos后面的数据长度了,所以只是把后面的数全部取出来,和pos+len的情况是一样,所以在这里就吧它俩当成一种情况

        使用substr()函数时要注意有没有深拷贝构造函数,程序会报错,需要提前写构造函数:

        改进过的流提取就节省了很多空间,这里是利用了数组open,来临时存储数据,数组满了,再直接利用操作符"+="操作即可。

        关于本章知识点如果有不足或者遗漏,欢迎大家指正,谢谢!!!

上一篇:linux服务器怎么拉黑ip?

下一篇:曙光服务器电源怎么启动?