• 【C++】STL —— String类不会怎么办? 看文档(万字详解)


    🌈欢迎来到C++专栏~~String类(万字详解)


    • (꒪ꇴ꒪(꒪ꇴ꒪ )🐣,我是Scort🎓
    • 🌍博客主页:张小姐的猫~江湖背景
    • 快上车🚘,握好方向盘跟我有一起打天下嘞!
    • 送给自己的一句鸡汤🤔:
    • 🔥真正的大师永远怀着一颗学徒的心
    • 作者水平很有限,如果发现错误,可在评论区指正,感谢🙏
    • 🎉🎉欢迎持续关注!
      在这里插入图片描述

    请添加图片描述

    请添加图片描述

    学习STL要多翻阅官方文档 cplusplus.com,话不多说,发车

    一. 编码科普

    为什么string不能针对char来写?因为编码不同。char只能表示256个字符。
    所以这时候要用模板。

    string管理的是一个char*的字符串。
    u16string:一个字符是两个字节
    u32string:一个字符是四个字节
    wstring:叫做宽字符,一个字符占两个字节

    🐋ASCII码

    ASCII码表。是美国设计的。
    ASCII码表是:计算机当中存的值,和字符的映射
    但是只有256个字符的表示。用char表示

    🐋Unicode

    也叫做万国码

    Unicode是针对全世界的语言而设计的一种编码。

    常见的有utf-8 utf-16 utf-32

    🐋gbk

    gbk是叫做国标码。是针对中文创建的一个编码。其中还涉及台湾的繁体字。

    计算机上不止有英文,还要有中文,日文等语言。但是ASCII码表不足以表示

    二. String类

    string类实际上是basic_string这个类模板的实例化 ——
    在这里插入图片描述

    其底层实现大概如下:

    template<class T>
    class basic_string
    {
    	// ...
    private:
    	T* _str; //动态申请的
        size_t _size;
        size_t _capacity;
    	// ...
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    我们发现字符串类型不仅仅只有字符串,为什么还会有类模板呢?这就涉及到不同编码规则问题

    ascii编码表(老美写的)中,将值和符号建立映射关系,1byte空间可以表示256个英文字符;再说unicode,是为了表示全世界文字的编码表,其中的utf-16方案,所有字符,无论中英还是啥,都是两字节表示。我们认识到的,字符可不简单的是char,还可以是wchar宽字符等等

    🔥下面介绍string类常用的接口 ,要熟练掌握,其余的用时查阅即可。在使用string类时,需要包含头文件#include以及展开命名空间using namespace std;

    三.构造 & 析构 & 赋值重载

    ⚡构造函数

    在这里插入图片描述

    展示:——
    在这里插入图片描述这里我们看见是一个空串,但是为了更好的兼容c,它后面是给了一个\0的,我在原始视图里发现

    在这里插入图片描述
    说明符合c字符串的规范

    其余的接口简单演示,主要为了演示如何查阅文档

    功能:从pos开始取对象的一部分(len)。

    substring (3)	string (const string& str, size_t pos, size_t len = npos);
    
    • 1

    其中len给了缺省值npos,npos是string类的一个静态成员变量,值为-1,换算成补码就是全1,赋值给了size_t,也就是整型的最大值4,294,967,295。那如果不传参数的话,基本上是有多少取多少。

    在这里插入图片描述
    在这里插入图片描述
    注:string类对象支持直接用cin和cout进行输入和输出,因为重载了流插入>>和流提取<<操作符(后面说)

    取字符串前n个(用的非常少)

    from sequence (5)	string (const char* s, size_t n);
    
    • 1

    在这里插入图片描述
    ⚡ 一键初始化

    fill (6)	string (size_t n, char c);
    
    • 1

    在这里插入图片描述

    析构函数(不重要)

    析构我们不管,对象出了作用域,自动调用的

    ⚡赋值重载

    在这里插入图片描述

    string s1;
    string s2 = "hello world";//构造+拷贝构造-》优化——直接构造
    
    s1 = s2;
    s1 = "xxxxx";
    s1 = 'y';
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    如果现在让我们取实现逆置一个字符串,我们又不能拿的到str(私有),何况我们都不知道底层是_str 还是str_ ,不清楚底层实现,这就要引出[]

    四.operator[ ]

    重载了[],使得string类可以像数组一样访问字符。不同的是,数组访问本质是解引用,而这里是调用函数。

    它提供了两个版本 ——

    在这里插入图片描述

    其大概的底层实现如下:

    char& operator[](size_t pos)//传引用返回,别名
    {
       assert(pos<_size);
       return _str[pos];
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    operator[]传引用返回,返回的是别名,这使得它可读可写

    这里不是为了减少拷贝,而是为了做输出型参数,支持修改返回值

    在这里插入图片描述

    #include
    #include
    using namespace std;
    
    int main()
    {
    	string s("more than words");
    	// 1.可读
    	//for (size_t i = 0; i < s.length(); i++)  二者都是求长度,string比较早,且不适合一些树的结构
    	for (size_t i = 0; i < s.size(); i++)
    	{
    		//等价于cout << s.operator[](i) << " " <<; 
    		cout << s[i] << ' ' ;
    	}
    	cout << endl;
        
    	// 2.可写
    	for (size_t i = 0; i < s.size(); i++)
    	{
    		s[i] += 1;
    	}
    	cout << s << endl;
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    在这里插入图片描述对于const修饰的就不能修改了

    const string s2("hello world");
    for (size_t i = 0; i < s1.size(); ++i)
    {
    	s2[i]++;//报错了
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    下面两个函数功能一致,(at的存在有历史原因)只不过二者检查越界的方式不同,推荐使用[] ——

    在这里插入图片描述

    五、Capacity 容量操作

    在这里插入图片描述

    ⚡size vs length

    ➰字符串中有效字符长度,即不包含最后作为结尾标识符的\0

    在这里插入图片描述

    两者底层实现完全一致(length的存在是历史原因),但强烈推荐使用size. 这是为了和后序各种容器接口保持一致(二叉树你不能用length吧)

    capacity

    容量:能存多少个有效字符(注意\0无效字符不算),要记得string类的底层是顺序表结构,初始值是15

    在这里插入图片描述

    ⚡resize vs reverse

    reserveresize 都是改变容量,申请至少n个字符的空间(字符串涉及对齐问题,后续详谈) ,但有所不同 ——

    🤞1. resize - 开空间,并可以对空间初始化

    在这里插入图片描述
    翻译知道

    • 如果是将元素个数减少,会把多出size的字符抹去,这不挺resize的吗(狗头)
    • 如果是将元素个数增多,void resize (size_t n);,用\0来填充多出的元素空间,void resize (size_t n, char c);字符c来填充多出的元素空间
    • 注:resize在改变元素个数时,如果是将元素个数增多,可能会改变容量的大小;如果是将元素个数size减少,容量不变
    void test_string14()
    {
    	string s1("JDG 总冠军");
    	s1.resize(5);//size缩小成5,capacity不变
    
    	string s2("JDG 总冠军");
    	s2.resize(100);//填充'\0',size——>100,capacity->111(自动扩容)
    
    	string s3("JDG 总冠军");
    	s3.resize(100,'~');//填充'\0',size——>100,capacity->111(自动扩容)
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    ➰ 2. reserve - 开空间。在已知需要多少空间时,调用reserve,可以避免频繁增容的消耗

    在这里插入图片描述

    • 为字符串预留空间改变容量。当然了不会改变有效元素个数size
    • 给reserve的参数n小于string的容量时,是无效请求,并不会改变容量大小
    #include
    
    using namespace std;
    
    int main()
    {
    	string s1;
    	s1.reserve(100); // size - 0,capcacity->111
    
    	string s2("more than words");
    	s2.reserve(5);   // capacity和size仍为15
    
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    ⚡clear

    清空有效字符,容量不变
    在这里插入图片描述

    ⚡empty

    检测字符串是否为空串

    在这里插入图片描述

    六、iterator 迭代器

    第二种遍历的方法:迭代器,对于string类,无论正着还是倒着走,[下标]的方法都足够好用,为什么还要有迭代器?
    🤞🤞事实上,迭代器是一种通用的遍历方式,且用法类似所有容器都可以使用迭代器这种方式去访问修改,而list、map/set不支持[下标]遍历。结论是,对于string类,我们得会用迭代器,但是我们更喜欢用[下标]

    🌈正向迭代器

    正向迭代器提供了两个函数——
    在这里插入图片描述

    在这里插入图片描述

    🌈迭代器 iterator是指针一样的类型,不确定是不是(薛定谔的猫),但它的用法像指针一样, 其区间[ }左闭右开

    #include
    #include
    
    using namespace std;
    
    int main()
    {
    	string s("more than words");
    	// 1.可读
    	string::iterator it = s.begin();
    	while (it != s.end())
    	{
    		cout << *it << " ";
    		it++;
    	}
    	cout << endl;
    
    	// 2.可写
    	it = s.begin();
    	while (it != s.end())
    	{
    		*it += 1;
    		it++;
    	}
    	cout << s <<endl;
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27

    在这里插入图片描述

    • iterator依然提供了两个版本,第二个是const变量
    • 关于遍历的时候!=能不能改成<= ,可以但是没必要,因为在string的物理空间是连续的,其他容器list等不一定连续。

    🌈反向迭代器

    也提供了两个成员函数

    在这里插入图片描述

    在这里插入图片描述

    void test_string5()
    {
    	string s("hello");
    	string::reverse_iterator rit = s.rbegin();
    	//auto rit = s.rbegin();//auto 可以自动推导类型
    	while (rit != s.rend())
    	{
    		cout << *rit << " ";
    		rit++;
    	}
    	cout << endl;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    在这里插入图片描述

    🌈const迭代器

    所谓的const迭代器就是针对const的版本嘛

    • 普通迭代器可读可写,相当于string类模板中,类型为T*
    • 而const迭代器不可写。这是因为是const成员函数,const修饰this指针指向的内容(相当于string类模板中,类型为const T*)

    const迭代器也分正向迭代器反向迭代器,且就是给const对象用的。这是因为const对象才能调用这里的const成员函数,返回const迭代器,不可写。

    在这里插入图片描述
    使用情况如下:

    void test_string6()
    {
    	string s("hello");
    	// const正向迭代器 - 可读不可写
    	string::const_iterator it = s.begin();
    	while (it != s.end())
    	{
    		cout << *it << " ";
    		it++;
    	}
    	cout << endl;
    
    	// const反向迭代器 - 可读不可写
    	string::const_reverse_iterator rit = s.rbegin();
    	while (rit != s.rend())
    	{
    		cout << *rit << " ";
    		rit++;
    	}
    	cout << endl;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    传参进func中,s是const对象,自动调用第二个接口,返回的是const_iterator,要用const迭代器类型接收,且不能修改

    在这里插入图片描述

    C++11为了区分const迭代器和普通迭代器还提供了以下接口,不然调用时容易混淆

    在这里插入图片描述

    🌈范围for遍历

    范围for是C++11提供的语法糖🍬,实际上底层编译器会替换成迭代器(反汇编里可以看出) 只能正向遍历

    🍬依次取s中的每个字符,赋值给ch

    • 自动迭代
    • 自动判断结束
    #include
    #include
    
    using namespace std;
    
    int main()
    {
    	string s("more than words");
    	for (auto& ch : s)
    	{
    		cout << ch << " ";
    	}
    	cout << endl;
    
    	for (auto& ch : s)
    	{
    		ch += 1;
    	}
    	cout << s << endl;
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    ps:

    • 若要修改,auto要加上&。因为*it会依次赋值给chch是*it的拷贝,*it改变不影响ch,所以要加上&

    七、Modifiers 修改

    🎨追加

    在这里插入图片描述

    +=最好用也最常用,因为既可以追加字符、也可追加字符串 ,其实底层调用了appendpush_back

    void test_string7()
    {
    	string s("hello");
    	s.push_back('-');
    	s.push_back('-');
    	s.append("world");
    	cout << s << endl;
    
    	string str("我来了");
    	s += '@';//字符
    	s += str;//字符串
    	s += "JDG总冠军";
    	cout << s << endl;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    在这里插入图片描述
    其中append的迭代器可以选择性的打印字符串内容(了解即可)

    string s("hello");
    string str("我来了");
    
    s.append(++str.begin(), --str.end());
    string copy(s.begin() + 5, s.end() -5);
    
    • 1
    • 2
    • 3
    • 4
    • 5

    在这里插入图片描述

    下面来研究尾插扩容容量变化 ——

    void test_string8()
    {
    	string s;
    	size_t sz = s.capacity();
    	cout << "making s grow:\n";
    	for (int i = 0; i < 100; ++i)
    	{
    		s.push_back('c');
    		if (sz != s.capacity())
    		{
    			sz = s.capacity();
    			cout << "capacity changed: " << sz << '\n';
    		}
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    我们可以看见在vs下增容,第一次是两倍,后面是1.5倍的增容

    在这里插入图片描述

    如果提前知道是多少空间,可以调用reserve预留空间,避免频繁增容的消耗

    s.resize(1000'x'); //开空间+初始化
    
    • 1

    在这里插入图片描述

    🎨插入和删除

    🐋尽量少使用头部的插入和删除,因为要挪动,O(N)效率低

    在这里插入图片描述

    🤞1️⃣小练习:在字符串中空格的地方插入一个%

    我的第一想法:遍历字符串,遇到' '的时候,直接插入

    void test_string9()
    {
    	//在空格的地方插入一个%
    	string str("JDG NB 总冠军");
    	for (size_t i = 0; i < str.size(); ++i)
    	{
    		if (str[i] == ' ')
    		{
    			str.insert(i, "20%");
    		}
    	}
    	cout << str << endl;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    但这样有没有问题呢?
    在这里插入图片描述

    那怎么样处理比较好呢?只需要在插入的地方i额外的+3

    void test_string9()
    {
    	//在空格的地方插入一个%
    	string str("JDG NB 总冠军");
    	for (size_t i = 0; i < str.size(); ++i)
    	{
    		if (str[i] == ' ')
    		{
    			str.insert(i, "20%");
    			i += 3;
    		}
    	}
    	cout << str << endl;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    2️⃣练习升级:把字符串中遇到的空格替换成20%

    这就要引入erase删除字符串中的字符
    在这里插入图片描述

    void test_string9()
    {
    	//在空格的地方插入一个%
    	string str("JDG NB 总冠军");
    	for (size_t i = 0; i < str.size(); ++i)
    	{
    		if (str[i] == ' ')
    		{
    			str.insert(i, "20%");
    			i += 3;
    		}
    	}
    	//再把空格删除掉哦
    	for (size_t i = 0; i < str.size(); ++i)
    	{
    		if (str[i] == ' ')
    		{
    			str.erase(i, 1);
    		}
    	}
    	cout << str << endl;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    ps:最好不要自行挪动数据,因为[]会检查下标位置必须要小于size的,如果真的要挪动,要resize一下,增加长度

    也有一种空间换时间的方法:创建新的串遍历,效率O(N)

    void test_string9()
    {
    	string str("JDG NB 总冠军");
    	string newstr;
    	for (size_t i = 0; i < str.size(); ++i)
    	{
    		if (str[i] != ' ')
    		{
    			newstr += str[i];
    		}
    		else
    		{
    			newstr += "20%";
    		}
    	}
    	cout << newstr << endl;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    八、String operations 字符串操作

    在这里插入图片描述
    打印字符串,都能打印,但意义不同 ——

    在这里插入图片描述

    🤞前者是string类的流插入运算符的重载,以对象size为准,size是多少打印多少
    后者是以常量字符串对象\0为准,遇到\0就结束(符合c语言标准)

    所以说\0不一定是结束标志,在string里会被忽视

    主要作用还是与函数接口接合——

    	string file("test.txt");	
    	FILE* fout = fopen(s.c_str(), "w");//打印文件
    
    • 1
    • 2

    ![在这里插入图片描述](https://img-blog.csdnimg.cn/631a160b51da4d7e9729bbeb05c5295d.png

    🌍substr 子串

    ➰· 取当前串的一个子串
    在这里插入图片描述

    len:如果len比能取到的串长或使用缺省值npos,都是能取多少取多少

    🌍查找 find & rfind

    🌊 1. 从字符串pos位置从前向后找字符c/字符串,返回该字符在字符串中的位置,找不到就返回npos

    在这里插入图片描述

    🌊 2. 从字符串pos位置倒着找找字符c/字符串,返回该字符在字符串中的位置

    在这里插入图片描述
    💢小练习:取字符串的后缀

    void test_string11()
    {
    	string str("test.cpp");
    	//找出后缀
    	size_t pos = str.rfind('.');//面对多后缀的最好用 rfind
    	if (pos != string::npos)
    	{
    		//string buff = str.substr(pos, str.size() - pos);
    		string buff = str.substr(pos);//因为是取到结束
    		cout << buff << endl;
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    在这里插入图片描述

    但是这样写有没有说明问题呢?如果后缀是test.cpp.tar.zip呢?要取最后一个后缀

    这样就要将find ——》 rfind,即可解决

    💢解析出网址的这三个部分:协议 - 域名 - 资源

    #include
    #include
    
    using namespace std;
    
    int main()
    {
    	string url = "https://cplusplus.com/reference/string/string/substr/";
    	size_t pos1 = url.find("://");
    	if (pos1 == string::npos)
    	{
    		cout << "非法字符串" << endl;
    		return;
    	}
    	//取协议
    	string protocol = url.substr(0, pos1);
    	cout << protocol << endl;
    
    	size_t pos2 = url.find('/', pos1 + 3);
    	if (pos1 == string::npos)
    	{
    		cout << "非法字符串" << endl;
    		return;
    	}
    	string domain = url.substr(pos1 + 3, pos2 - pos1 - 3);//取域名
    	cout << domain << endl;
    
    	string uri = url.substr(pos2 + 1);//取资源
    	cout << uri << endl;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30

    在这里插入图片描述

    💢find 和find_first_of 区别

    在这里插入图片描述
    find_first_of:只要出现要寻找的串里的任意字符都找出来

    吐槽一下:find_first_of 更应该叫find_any_of,但我们要尊重语法

    在这里插入图片描述

    九、非成员函数重载

    💦流插入&流提取

    注意注意:流插入和流提取都是以空格、回车作为结束标志的。这意味着如果想要输入一个字符串,最终可能只读入了一个单词,剩余的留在缓冲区里。

    在这里插入图片描述

    于是我们引入了getline,做题会遇到

    💦getline

    在这里插入图片描述

    遇到换行才结束

    💢小练习:输出一个整数,表示输入字符串最后一个单词的长度

    #include 
    #include 
    using namespace std;
    
    int main() {
        string str;
        getline(cin,str);
        size_t pos = str.rfind(' ');
        if(pos != string::npos)
        {
            cout<<str.size()-pos-1<<endl;
        }
        else{
            cout<<str.size()<<endl;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    在这里插入图片描述

    💦to_string

    在这里插入图片描述

    void test_string12()
    {
    	//整形转字符串
    	int ival;
    	double dval;
    	cin >> ival >> dval;
    	string istr = to_string(ival);
    	string dstr = to_string(dval);
    	cout << istr << endl;
    	cout << dstr << endl;
    
    	//字符串转整形
    	istr = "9999";
    	dstr = "9999.99";
    	ival = stoi(istr);
    	dval = stod(dstr);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    重要的事情说三遍:不会的查文档不会的查文档不会的查文档!!

    十、 vs和g++下string结构的说明(了解)

    🎉VS下string结构的说明

    string总共占28个字节,内部结构稍微复杂一点,先是有一个联合体联合体用来定义string中字符串的存储空间:

    • 当字符串长度小于16时,使用内部固定的字符数组来存放
    • 当字符串长度大于16时,从堆上开辟空间
    union _Bxty
    { // storage for small buffer or pointer to larger one
    	value_type _Buf[_BUF_SIZE];
    	pointer _Ptr;
    	char _Alias[_BUF_SIZE]; // to permit aliasing
    } _Bx;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    这种设计也是有一定道理的,大多数情况下字符串的长度都小于16,那string对象创建好之后,内部已经有了16个字符数组的固定空间,不需要通过堆创建,效率高。
    其次:还有一个size_t字段保存字符串长度,一个size_t字段保存从堆上开辟空间总的容量, 最后:还有一个指针做一些其他事情。
    故总共占16+4+4+4=28个字节。

    在这里插入图片描述

    🎉g++下string的结构
    G++下,string是通过写时拷贝实现的,string对象总共占4个字节,内部只包含了一个指针,该指针将来指向一块堆空间,内部包含了如下字段:

    • 空间总大小
    • 字符串有效长度
    • 引用计数
    • 指向堆空间的指针,用来存储字符串。
    struct _Rep_base
    {
    	size_type _M_length;
    	size_type _M_capacity;
    	_Atomic_word _M_refcount;
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    📢写在最后

    1024程序节,快要来了,大家会怎么样过呢

    在这里插入图片描述

  • 相关阅读:
    P2602 [ZJOI2010] 数字计数(数位dp入门题)
    安卓机型传感器分区故障persist的相关说明 修复步骤
    ES6 高阶函数的使用详解
    Java服务总在半夜挂,背后的真相竟然是...
    风控中策略规则发现的两种模型方法
    充分利用自动化测试的 10 个最佳实践
    c++标准库学习-filesystem文件系统库(1)-path对象
    在vue项目中使用electron
    如何选择适合企业的SQL开发工具
    css画一条0.5px的直线
  • 原文地址:https://blog.csdn.net/qq_42996461/article/details/127445917