STL指的是C++标准模板库(Standard Template Library),是一个C++中的通用库,包括许多常用的数据结构和算法,如vector、list、set、map、sort、find等。STL库的主要目标是提供一组高效、可靠、通用的模板类和函数,方便开发者使用,提高开发效率和代码质量。STL是C++标准库的重要组成部分,也是C++编程中不可或缺的一部分。
STL(Standard Template Library)是由Alexander Stepanov和Meng Lee于1994年首次提出的。Alexander Stepanov是惠普公司(HP)的研究员,他在1983年到1994年期间在惠普公司工作,期间他开始了STL的研究和开发工作。Meng Lee是斯坦福大学的一位教授,他是Alexander Stepanov的学生,参与了STL的开发工作。
1994年,STL第一次公开发表,被纳入到C++标准库中。1998年,C++标准库正式发布,STL被正式纳入其中。2000年,STLport项目开始,旨在将STL移植到不同的编译器和操作系统中,并保持其兼容性。
随着C++标准的不断发展,STL的发展也在不断地推进。在C++11中,STL引入了新的特性和数据结构,如unordered_set、unordered_map、array等。在C++17中,STL也引入了更多的更新和改进,如parallel algorithms等。
总之,STL的发展历程是与C++标准库的发展密不可分的。随着C++的不断发展,STL也在不断地完善和发展。
STL分为许多版本,这里主要介绍常见的版本:原始版(HP版本),它是所有STL的鼻祖,对程序开发做出了不可磨灭的贡献。P.J版本,大家用的VS上采用的就是这个版本。SGI版本由Silicon Graphics Computer Systems,Inc公司开发,继承自HP版 本。被GCC(Linux)采用,可移植性好, 可公开、修改甚至贩卖,从命名风格和编程 风格上看,阅读性非常高。
STL六大组件分别是容器、算法、迭代器、仿函数、空间配置器和配接器。在后面的学习中会一一具体介绍。这里简单了解即可。
在正式介绍string类之前,推荐两个在线的c++文档查询网站,对于我们c++的学习非常有帮助。 官网和非官方。这里推荐使用非官方的在线文档,因为比较简洁方便查找。当然官方的文档非常详细,两者各有优势,可以按照喜好自行选择。
string是C++标准库中的一个类,用于处理字符串。string类的本质就是管理字符串的顺序表。
下面就正式开始介绍string类。
string类一共提供了7种构造函数,分别是(1)无参构造。(2)拷贝构造。(3)拷贝子串构造,即从源string类的pos位置拷贝len个字符进行构造、(4)用c字符串构造,c字符串指的是c语言下以’\0’作为结束标识符的字符数组。(5)取c字符串中的n个字符进行构造。(6) 以n个字符来进行构造。(7)迭代器范围进行初始化,这里不重点讲,后面会介绍迭代器。
下面简单介绍一下(3)
//substring (3)
string (const string& str, size_t pos, size_t len = npos);
这里的缺省参数npos其实是一个静态成员变量,表示的是4294967295。即0xffffffff。
其实就是将源string类的pos下标处的字符开始,拷贝len个字符进行构造
#include
#include
using namespace std;
int main()
{
string str1("hello world");
string str2(str1, 6, 5);
string str3(str1,6);
cout << str2 << endl;
cout << str3 << endl;
return 0;
}
析构函数和赋值等号重载就简单看看就行。析构函数就是清理string类实例化对象的资源。赋值等号重载,就是给string类实例化的对象赋值,使当前值被替换。
#include
#include
using namespace std;
int main()
{
string str1;
str1 = "abcde";
cout << str1 << endl;
str1 = 'c';
cout << str1 << endl;
return 0;
}
int main()
{
string str1;
cin >> str1;
cout << str1 << endl;
return 0;
}
这里个接口都是用来给string类实例化出的对象进行尾插字符或字符串的。push_back是在string类对象后尾插一个字符。append是在当前string类对象后追加字符、字符串、string类对象等等。
这里的接口其实和上面介绍的构造函数的重载的参数方面就可以大概猜测到append对应的不同参数的功能,这里我就不重复介绍,浅浅谈一下第(2)个接口,它是追加一个string类对象中的一部分,也就是子串。但是他的第三个参数并没有给默认参数,这一点其实就跟上面的构造有些许设计上的不同,这也是string类比较为人诟病的一点,就是参数的设计没有很好的延续性。
int main()
{
string s1("hello");
cout << s1 << endl;
s1.push_back(' ');
s1.append("world");
cout << s1 << endl;
return 0;
}
加操作符重载和加等操作符重载都是在string类对象的尾部插入字符或字符串。+操作符比较少用主要还是用的+=操作符。加等运算符重载是一个公共成员函数,加运算符重载为了支持给字符、字符串追加string类对象的操作,所以是非成员函数。
#include
#include
using namespace std;
int main()
{
string s1("hello world");
cout << s1 << endl;
string s2 = s1 + "你好";
cout << s2 << endl;
s2 = s2 + 'C';
cout << s2 << endl;
s2 = s2 + s2;
cout << s2 << endl;
return 0;
}
其实+=运算符重载的底层实现其实就是复用上面的两个接口,当调用+=后面跟的是string类对象或字符串时,编译器就会调用append。当调用+=后面跟的是字符时,编译器就会调用push_back。从使用的角度出发,用+=运算符还是比较舒服的。
int main()
{
string s1("hello world");
cout << s1 << endl;
s1 += "你好";
cout << s1 << endl;
s1 += 'C';
cout << s1 << endl;
string s2("xxxxxxxxx");
s1 += s2;
cout << s1 << endl;
return 0;
}
为什么string类不像我们之前学习的c字符串,需要我们自己确定大小,以避免溢出。是因为string的底层实现类似于顺序表的机制,空间不够了可以自动扩容。