admin管理员组

文章数量:1028576

【C++】STL:Sring模拟实现

类似于C++标准库中的std::string,基于此模拟实现一个自己的MyString::string类。源码在这,欢迎大家斧正和提出建议。string模拟实现

1.初步实现

基于string类是主要针对字符串的操作,所以我们需要知道一个字符串的内容、长度、可分配容量,有时还需要一个无效位置来进行判断。

所以我们的类的成员变量应包括以下几个:

  • [_str]:指向动态分配的字符数组,用于存储字符串内容。
  • [_size]:当前字符串的长度(不包括终止符 \0)。
  • [_capacity]:当前分配的字符数组的容量(包括终止符 \0)。
  • [npos]:静态成员变量,表示无效位置,值为 -1。对此在官网也有记载:
image-20250424102734800

把它们放在private中:

代码语言:javascript代码运行次数:0运行复制
private:
        char *_str;
        size_t _size;
        size_t _capacity;
        static size_t npos;

同时作为一个类,应该包含构造函数和析构函数。

对于构造函数,又分为有参、无参、拷贝构造函数。

代码语言:javascript代码运行次数:0运行复制
//无参构造函数
        string()
        {
            _str = new char[1]; // 分配一个字符的内存
            _str[0] = '\0'; // 初始化为空字符串
            _size = 0;
            _capacity = 1; // 容量为1
        }
//有参构造函数
        string(const char *str) // 初始化列表
            : _str(new char[_capacity + 1]) 
            , _size(strlen(str))
            , _capacity(_size)
        {
            strcpy(_str, str); // 复制字符串
        }
//拷贝构造函数
	    string(const string &other)
        {
            _size = other._size;                       // 复制大小
            _capacity = other._capacity;               // 复制容量
            _str = new char[_capacity + 1];            // 分配内存
            memcpy(_str, other._str, other._size + 1); // 复制字符串
        }

以及析构函数:

代码语言:javascript代码运行次数:0运行复制
// 析构函数
        ~string()
        {
            delete[] _str; // 释放内存
            _str = nullptr;
            _size = 0;
            _capacity = 0;
        }

2. 支持的功能

(1) 迭代器支持
  • 提供 begin()end() 方法,支持范围 for 循环和迭代器操作。
  • 提供 const 版本的 begin() end(),支持常量对象的迭代。
代码语言:javascript代码运行次数:0运行复制
typedef char *iterator;

        iterator begin()
        {
            return _str;
        }
        iterator end()
        {
            return _str + _size;
        }

        iterator begin() const
        {
            return _str;
        }
        iterator end() const
        {
            return _str + _size;
        }
(2) 字符串的基本操作
  • c_str()
    • 返回 C 风格字符串(以 \0 结尾)。
  • size()
    • 返回字符串的长度(不包括终止符 \0)。
  • operator[]
    • 支持通过下标访问字符串中的字符。
    • 提供 const 和非 const 版本。
代码语言:javascript代码运行次数:0运行复制
	   const char *c_str()
        {
            return _str; // 返回字符串
        }

       size_t size() const
        {
            return _size;
        }

       char &operator[](size_t pos)
        {
            assert(pos < _size);
            return _str[pos];
        }
       char &operator[](size_t pos) const
        {
            assert(pos < _size);
            return _str[pos];
        }
(3) 增删改查功能

该部分的内容都基于待会会介绍的内存管理功能。同时基于该部分的其他方法,某些方法会直接进行复用,从而达到节省代码量和提高可读性的效果。

增与改

push_back(char ch):在字符串末尾添加一个字符。

代码语言:javascript代码运行次数:0运行复制
void push_back(char ch)
        {
            if (_size == _capacity)
            {
                // 2倍扩容
                reserve(_capacity == 0 ? 4 : _capacity * 2);
            }
            _str[_size] = ch;
            ++_size;
            _str[_size] = '\0';
        }

append(const char* str):在字符串末尾追加一个 C 风格字符串。

代码语言:javascript代码运行次数:0运行复制
void append(const char *str)
        {
            size_t len = strlen(str);
            if (_size + len > _capacity)
            {
                // 至少_size + len
                reserve(_size + len);
            }

            strcpy(_str + _size, str);
            _size += len;
        }

operator+=(char ch)operator+=(const char* str):支持通过 += 运算符追加字符或字符串。

代码语言:javascript代码运行次数:0运行复制
 string &operator+=(char ch)
        {
            push_back(ch);
            return *this;
        }
 string &operator+=(const char *str)
        {
            append(str);
            return *this;
        }

insert(size_t pos, size_t n, char ch):在指定位置插入 [n](vscode-file://vscode-app/d:/Microsoft VS Code/resources/app/out/vs/code/electron-sandbox/workbench/workbench.html) 个字符。

insert(size_t pos, const char* str):在指定位置插入一个 C 风格字符串。

代码语言:javascript代码运行次数:0运行复制
 void insert(size_t pos, size_t n, char ch)
        {
            assert(pos <= _size);
            if (_size + n > _capacity)
            {
                // 至少_size + n
                reserve(_size + n);
            }
            // int end = _size;
            size_t end = _size;

            // if(pos = 0)
            // {

            // }
            while (end >= pos && end != npos)
            {
                _str[end + n] = _str[end];
                end--;
            }

            for (size_t i = 0; i < n; i++)
            {
                _str[pos + i] = ch;
            }
            _size += n;
        }

   void insert(size_t pos, const char *str)
        {
            assert(pos <= _size);
            size_t len = strlen(str);
            if (_size + len >= _capacity)
            {
                reserve(_size + len);
            }
            size_t end = _size;
            while (end >= pos && end != npos)
            {
                _str[end + len] = _str[end];
                end--;
            }
            for (size_t i = 0; i < len; i++)
            {
                _str[pos + i] = str[i];
            }
            _size += len;
        }

resize(size_t n, char ch = '\0'):调整字符串长度,多余部分用指定字符填充,或截断字符串。

代码语言:javascript代码运行次数:0运行复制
void resize(size_t n, char ch = '\0') // 这里缺省值设为'\0'
        {
            if (n < _size)
            {
                _size = n;
                _str[_size] = '\0';
            }
            else
            {
                reserve(n);

                for (size_t i = _size; i < n; i++)
                {
                    _str[i] = ch;
                }
                _size = n;
                _str[_size] = '\0';
            }
        }

erase(size_t pos, size_t len = npos):从指定位置开始删除指定长度的字符。

代码语言:javascript代码运行次数:0运行复制
void erase(size_t pos, size_t len = npos)
        {
            assert(pos <= _size);
            if (len == npos || pos + len >= _size)
            {
                _str[pos] = '\0';
                _size = pos;
                _str[_size] = '\0';
            }
            else
            {
                size_t end = pos + len;
                while (end <= _size)
                {
                    _str[pos++] = _str[end++];
                }
                _size -= len;
            }
        }

find(char ch, size_t pos = 0):从指定位置开始查找字符,返回其位置。

find(const char* str, size_t pos = 0):从指定位置开始查找子字符串,返回其起始位置。

代码语言:javascript代码运行次数:0运行复制
size_t find(char ch, size_t pos = 0)
        {
            assert(pos < _size);
            for (size_t i = pos; i < _size; i++)
            {
                if (_str[i] == ch)
                {
                    return i;
                }
            }
            return npos;
        }
        size_t find(const char *str, size_t pos = 0)
        {
            assert(pos < _size);

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

substr(size_t pos = 0, size_t len = npos):返回从指定位置开始的子字符串。

代码语言:javascript代码运行次数:0运行复制
string substr(size_t pos = 0, size_t len = npos)
        {
            assert(pos < _size);
            size_t n = len;
            if (len == npos || pos + len > _size)
            {
                n = _size - pos;
            }
            string tmp;
            tmp.reserve(n);
            // for (size_t i = pos; i < n; i++) i不是从0开始,所以应该是pos+n
            for (size_t i = pos; i < n + pos; i++)
            {
                tmp += _str[i];
            }
            return tmp;
        }
(4) 比较操作
  • operator<:支持字符串的字典序比较。
  • operator==:支持字符串的相等比较。
  • operator<=operator>operator>=operator!=:支持其他常见的比较操作。
代码语言:javascript代码运行次数:0运行复制
bool operator<(const string &s)
        {
            int ret = memcmp(_str , s._str,_size < s._size? _size: s._size);
            return ret == 0 ? _size < s._size : ret< 0;   
        }

        bool operator==(const string &s)
        {
            return _size == s._size
                && memcmp(_str,s._str,_size)== 0;
        }

        bool operator<=(const string &s)
        {
            return *this < s || *this == s;
        }
        bool operator>(const string &s)
        {
            return !(*this <= s);
        }
        bool operator>=(const string &s)
        {
            return !(*this < s);
        }
        bool operator!=(const string &s)
        {
            return !(*this == s);
        }
(5) 内存管理

reserve(size_t n)

  • 扩展字符串的容量,避免频繁的内存分配。
代码语言:javascript代码运行次数:0运行复制
void reserve(size_t n)
        {
            if (n > _capacity)
            {
                char *tmp = new char[n + 1]; // + "\0"
                strcpy(tmp, _str);
                delete[] _str;
                _str = tmp;
                _capacity = n;
            }
        }

clear()

  • 清空字符串内容,将其重置为空字符串。
代码语言:javascript代码运行次数:0运行复制
void clear()
        {
            _str[0] = '\0';
            _size = 0;
        }

swap(string& s)

  • 交换两个字符串对象的内容,避免不必要的拷贝。
代码语言:javascript代码运行次数:0运行复制
void swap(string &s)
        {
            std::swap(_str,s._str);
            std::swap(_size,s._size);
            std::swap(_capacity,s._capacity);
        }

operator=(string tmp)

  • 赋值操作
代码语言:javascript代码运行次数:0运行复制
string& operator=(string tmp)
        {
            swap(tmp);
            return *this;
        }
(6) 流操作
  • operator<<
    • 支持将字符串输出到输出流。
  • operator>>
    • 支持从输入流读取字符串,自动处理空格和换行符。
代码语言:javascript代码运行次数:0运行复制
   size_t string::npos = -1;

    // 流插入和流提取
    ostream &operator<<(ostream &out, const string &s)
    {
        // for (size_t i = 0; i < s.size(); i++)
        // {
        //     /* code */
        //     out << s[i];
        // }
        for (auto ch : s)
        {
            out << ch;
        }
        return out;
    }

    istream &operator>>(istream &in, string &s)
    {
        s.clear();
        char ch = in.get();

        //  处理缓冲区前面的空格或者换行
        while (ch != ' ' && ch != '\n')
        {
            ch = in.get();
        }

        //  建立缓冲区,使空间扩容更加节省
        char buff[128];
        int i = 0;
        // in >> ch;
        while (ch != ' ' && ch != '\n')
        {
            buff[i++] = ch;
            if (i == 127) // 要给\0留一个
            {
                buff[i] = '\0';
                s += buff;
                i = 0;
            }
            // s += ch;
            // in >> ch;
            ch = in.get();
        }

        if (i != 0)
        {
            buff[i] = '\0';
            s += buff;
        }
        return in;
    }

3. 支持的运算符重载

  • 赋值运算符
    • 支持拷贝赋值和移动赋值。
  • 比较运算符
    • <==<=>>=!=
  • 字符串拼接运算符
    • +=(支持字符和字符串)。
  • 流插入和提取运算符
    • <<>>

4. 内存管理

  • 动态分配内存存储字符串内容,支持自动扩容。
  • 在析构函数中释放内存,避免内存泄漏。
  • 使用 swap 函数优化赋值运算符的实现,避免不必要的拷贝。

5. 与 [std::string]的对比

MyString::string 类与 [std::string]类非常相似,但仍有一些功能未实现,例如:

  1. [std::string] 的 replace 方法:替换字符串中的某些部分。
  2. [std::string] 的 compare 方法:提供更灵活的字符串比较功能。
  3. [std::string] 的 find_last_offind_first_of 方法:支持更复杂的查找操作。
  4. 线程安全性:[std::string]在某些实现中是线程安全的,而你的实现没有考虑线程安全。

当然,这仅仅是string类的冰山一角。MyString仅仅是对其的一个很简单的模拟实现,为的是理解string类的用法和意义。在自己模拟实现之后,往往在字符串的操作方面能够更加得心应手。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。 原始发表:2025-04-24,如有侵权请联系 cloudcommunity@tencent 删除c++sizestl函数字符串

【C++】STL:Sring模拟实现

类似于C++标准库中的std::string,基于此模拟实现一个自己的MyString::string类。源码在这,欢迎大家斧正和提出建议。string模拟实现

1.初步实现

基于string类是主要针对字符串的操作,所以我们需要知道一个字符串的内容、长度、可分配容量,有时还需要一个无效位置来进行判断。

所以我们的类的成员变量应包括以下几个:

  • [_str]:指向动态分配的字符数组,用于存储字符串内容。
  • [_size]:当前字符串的长度(不包括终止符 \0)。
  • [_capacity]:当前分配的字符数组的容量(包括终止符 \0)。
  • [npos]:静态成员变量,表示无效位置,值为 -1。对此在官网也有记载:
image-20250424102734800

把它们放在private中:

代码语言:javascript代码运行次数:0运行复制
private:
        char *_str;
        size_t _size;
        size_t _capacity;
        static size_t npos;

同时作为一个类,应该包含构造函数和析构函数。

对于构造函数,又分为有参、无参、拷贝构造函数。

代码语言:javascript代码运行次数:0运行复制
//无参构造函数
        string()
        {
            _str = new char[1]; // 分配一个字符的内存
            _str[0] = '\0'; // 初始化为空字符串
            _size = 0;
            _capacity = 1; // 容量为1
        }
//有参构造函数
        string(const char *str) // 初始化列表
            : _str(new char[_capacity + 1]) 
            , _size(strlen(str))
            , _capacity(_size)
        {
            strcpy(_str, str); // 复制字符串
        }
//拷贝构造函数
	    string(const string &other)
        {
            _size = other._size;                       // 复制大小
            _capacity = other._capacity;               // 复制容量
            _str = new char[_capacity + 1];            // 分配内存
            memcpy(_str, other._str, other._size + 1); // 复制字符串
        }

以及析构函数:

代码语言:javascript代码运行次数:0运行复制
// 析构函数
        ~string()
        {
            delete[] _str; // 释放内存
            _str = nullptr;
            _size = 0;
            _capacity = 0;
        }

2. 支持的功能

(1) 迭代器支持
  • 提供 begin()end() 方法,支持范围 for 循环和迭代器操作。
  • 提供 const 版本的 begin() end(),支持常量对象的迭代。
代码语言:javascript代码运行次数:0运行复制
typedef char *iterator;

        iterator begin()
        {
            return _str;
        }
        iterator end()
        {
            return _str + _size;
        }

        iterator begin() const
        {
            return _str;
        }
        iterator end() const
        {
            return _str + _size;
        }
(2) 字符串的基本操作
  • c_str()
    • 返回 C 风格字符串(以 \0 结尾)。
  • size()
    • 返回字符串的长度(不包括终止符 \0)。
  • operator[]
    • 支持通过下标访问字符串中的字符。
    • 提供 const 和非 const 版本。
代码语言:javascript代码运行次数:0运行复制
	   const char *c_str()
        {
            return _str; // 返回字符串
        }

       size_t size() const
        {
            return _size;
        }

       char &operator[](size_t pos)
        {
            assert(pos < _size);
            return _str[pos];
        }
       char &operator[](size_t pos) const
        {
            assert(pos < _size);
            return _str[pos];
        }
(3) 增删改查功能

该部分的内容都基于待会会介绍的内存管理功能。同时基于该部分的其他方法,某些方法会直接进行复用,从而达到节省代码量和提高可读性的效果。

增与改

push_back(char ch):在字符串末尾添加一个字符。

代码语言:javascript代码运行次数:0运行复制
void push_back(char ch)
        {
            if (_size == _capacity)
            {
                // 2倍扩容
                reserve(_capacity == 0 ? 4 : _capacity * 2);
            }
            _str[_size] = ch;
            ++_size;
            _str[_size] = '\0';
        }

append(const char* str):在字符串末尾追加一个 C 风格字符串。

代码语言:javascript代码运行次数:0运行复制
void append(const char *str)
        {
            size_t len = strlen(str);
            if (_size + len > _capacity)
            {
                // 至少_size + len
                reserve(_size + len);
            }

            strcpy(_str + _size, str);
            _size += len;
        }

operator+=(char ch)operator+=(const char* str):支持通过 += 运算符追加字符或字符串。

代码语言:javascript代码运行次数:0运行复制
 string &operator+=(char ch)
        {
            push_back(ch);
            return *this;
        }
 string &operator+=(const char *str)
        {
            append(str);
            return *this;
        }

insert(size_t pos, size_t n, char ch):在指定位置插入 [n](vscode-file://vscode-app/d:/Microsoft VS Code/resources/app/out/vs/code/electron-sandbox/workbench/workbench.html) 个字符。

insert(size_t pos, const char* str):在指定位置插入一个 C 风格字符串。

代码语言:javascript代码运行次数:0运行复制
 void insert(size_t pos, size_t n, char ch)
        {
            assert(pos <= _size);
            if (_size + n > _capacity)
            {
                // 至少_size + n
                reserve(_size + n);
            }
            // int end = _size;
            size_t end = _size;

            // if(pos = 0)
            // {

            // }
            while (end >= pos && end != npos)
            {
                _str[end + n] = _str[end];
                end--;
            }

            for (size_t i = 0; i < n; i++)
            {
                _str[pos + i] = ch;
            }
            _size += n;
        }

   void insert(size_t pos, const char *str)
        {
            assert(pos <= _size);
            size_t len = strlen(str);
            if (_size + len >= _capacity)
            {
                reserve(_size + len);
            }
            size_t end = _size;
            while (end >= pos && end != npos)
            {
                _str[end + len] = _str[end];
                end--;
            }
            for (size_t i = 0; i < len; i++)
            {
                _str[pos + i] = str[i];
            }
            _size += len;
        }

resize(size_t n, char ch = '\0'):调整字符串长度,多余部分用指定字符填充,或截断字符串。

代码语言:javascript代码运行次数:0运行复制
void resize(size_t n, char ch = '\0') // 这里缺省值设为'\0'
        {
            if (n < _size)
            {
                _size = n;
                _str[_size] = '\0';
            }
            else
            {
                reserve(n);

                for (size_t i = _size; i < n; i++)
                {
                    _str[i] = ch;
                }
                _size = n;
                _str[_size] = '\0';
            }
        }

erase(size_t pos, size_t len = npos):从指定位置开始删除指定长度的字符。

代码语言:javascript代码运行次数:0运行复制
void erase(size_t pos, size_t len = npos)
        {
            assert(pos <= _size);
            if (len == npos || pos + len >= _size)
            {
                _str[pos] = '\0';
                _size = pos;
                _str[_size] = '\0';
            }
            else
            {
                size_t end = pos + len;
                while (end <= _size)
                {
                    _str[pos++] = _str[end++];
                }
                _size -= len;
            }
        }

find(char ch, size_t pos = 0):从指定位置开始查找字符,返回其位置。

find(const char* str, size_t pos = 0):从指定位置开始查找子字符串,返回其起始位置。

代码语言:javascript代码运行次数:0运行复制
size_t find(char ch, size_t pos = 0)
        {
            assert(pos < _size);
            for (size_t i = pos; i < _size; i++)
            {
                if (_str[i] == ch)
                {
                    return i;
                }
            }
            return npos;
        }
        size_t find(const char *str, size_t pos = 0)
        {
            assert(pos < _size);

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

substr(size_t pos = 0, size_t len = npos):返回从指定位置开始的子字符串。

代码语言:javascript代码运行次数:0运行复制
string substr(size_t pos = 0, size_t len = npos)
        {
            assert(pos < _size);
            size_t n = len;
            if (len == npos || pos + len > _size)
            {
                n = _size - pos;
            }
            string tmp;
            tmp.reserve(n);
            // for (size_t i = pos; i < n; i++) i不是从0开始,所以应该是pos+n
            for (size_t i = pos; i < n + pos; i++)
            {
                tmp += _str[i];
            }
            return tmp;
        }
(4) 比较操作
  • operator<:支持字符串的字典序比较。
  • operator==:支持字符串的相等比较。
  • operator<=operator>operator>=operator!=:支持其他常见的比较操作。
代码语言:javascript代码运行次数:0运行复制
bool operator<(const string &s)
        {
            int ret = memcmp(_str , s._str,_size < s._size? _size: s._size);
            return ret == 0 ? _size < s._size : ret< 0;   
        }

        bool operator==(const string &s)
        {
            return _size == s._size
                && memcmp(_str,s._str,_size)== 0;
        }

        bool operator<=(const string &s)
        {
            return *this < s || *this == s;
        }
        bool operator>(const string &s)
        {
            return !(*this <= s);
        }
        bool operator>=(const string &s)
        {
            return !(*this < s);
        }
        bool operator!=(const string &s)
        {
            return !(*this == s);
        }
(5) 内存管理

reserve(size_t n)

  • 扩展字符串的容量,避免频繁的内存分配。
代码语言:javascript代码运行次数:0运行复制
void reserve(size_t n)
        {
            if (n > _capacity)
            {
                char *tmp = new char[n + 1]; // + "\0"
                strcpy(tmp, _str);
                delete[] _str;
                _str = tmp;
                _capacity = n;
            }
        }

clear()

  • 清空字符串内容,将其重置为空字符串。
代码语言:javascript代码运行次数:0运行复制
void clear()
        {
            _str[0] = '\0';
            _size = 0;
        }

swap(string& s)

  • 交换两个字符串对象的内容,避免不必要的拷贝。
代码语言:javascript代码运行次数:0运行复制
void swap(string &s)
        {
            std::swap(_str,s._str);
            std::swap(_size,s._size);
            std::swap(_capacity,s._capacity);
        }

operator=(string tmp)

  • 赋值操作
代码语言:javascript代码运行次数:0运行复制
string& operator=(string tmp)
        {
            swap(tmp);
            return *this;
        }
(6) 流操作
  • operator<<
    • 支持将字符串输出到输出流。
  • operator>>
    • 支持从输入流读取字符串,自动处理空格和换行符。
代码语言:javascript代码运行次数:0运行复制
   size_t string::npos = -1;

    // 流插入和流提取
    ostream &operator<<(ostream &out, const string &s)
    {
        // for (size_t i = 0; i < s.size(); i++)
        // {
        //     /* code */
        //     out << s[i];
        // }
        for (auto ch : s)
        {
            out << ch;
        }
        return out;
    }

    istream &operator>>(istream &in, string &s)
    {
        s.clear();
        char ch = in.get();

        //  处理缓冲区前面的空格或者换行
        while (ch != ' ' && ch != '\n')
        {
            ch = in.get();
        }

        //  建立缓冲区,使空间扩容更加节省
        char buff[128];
        int i = 0;
        // in >> ch;
        while (ch != ' ' && ch != '\n')
        {
            buff[i++] = ch;
            if (i == 127) // 要给\0留一个
            {
                buff[i] = '\0';
                s += buff;
                i = 0;
            }
            // s += ch;
            // in >> ch;
            ch = in.get();
        }

        if (i != 0)
        {
            buff[i] = '\0';
            s += buff;
        }
        return in;
    }

3. 支持的运算符重载

  • 赋值运算符
    • 支持拷贝赋值和移动赋值。
  • 比较运算符
    • <==<=>>=!=
  • 字符串拼接运算符
    • +=(支持字符和字符串)。
  • 流插入和提取运算符
    • <<>>

4. 内存管理

  • 动态分配内存存储字符串内容,支持自动扩容。
  • 在析构函数中释放内存,避免内存泄漏。
  • 使用 swap 函数优化赋值运算符的实现,避免不必要的拷贝。

5. 与 [std::string]的对比

MyString::string 类与 [std::string]类非常相似,但仍有一些功能未实现,例如:

  1. [std::string] 的 replace 方法:替换字符串中的某些部分。
  2. [std::string] 的 compare 方法:提供更灵活的字符串比较功能。
  3. [std::string] 的 find_last_offind_first_of 方法:支持更复杂的查找操作。
  4. 线程安全性:[std::string]在某些实现中是线程安全的,而你的实现没有考虑线程安全。

当然,这仅仅是string类的冰山一角。MyString仅仅是对其的一个很简单的模拟实现,为的是理解string类的用法和意义。在自己模拟实现之后,往往在字符串的操作方面能够更加得心应手。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。 原始发表:2025-04-24,如有侵权请联系 cloudcommunity@tencent 删除c++sizestl函数字符串

本文标签: CSTLSring模拟实现