
一.STL简介(了解)
1.什么是STL
STL(standard template libaray-标准模板库): 是C++标准库的重要组成部分,不仅是一个可复用的组件库,而且 是一个包罗数据结构与算法的软件框架。,是一个高效的c++程序库
2.STL的六大组件
组件名称 | 说明 |
---|
Container(容器) 各种基本数据结构 | 向量(vector)、双端队列(deque)、列表(list)、集合(set)、多重集合(multiset)、映射(map)和多重映射(multimap),string | Adapter(适配器) 可改变containers、Iterators或Function object接口的一种组件 | 为已有的类提供新的接口,目的是简化、约束、使之安全、隐藏或者改变被修改类提供的服务集合 | Algorithm(算法) 各种基本算法如sort、search…等 | 算法Algorithms,用来处理群集内的元素。它们可以出于不同的目的而搜寻、排序、修改、使用那些元素。通过迭代器的协助,我们可以只需编写一次算法,就可以将它应用于任意容器,这是因为所有的容器迭代器都提供一致的接口 | Iterator(迭代器) 连接containers和algorithms | 1.迭代器Iterators,用来在一个对象群集(collection of objects)的元素上进行遍历。这个对象群集或许是个容器,或许是容器的一部分。迭代器的主要好处是,为所有容器提供了一组很小的公共接口。迭代器以++进行累进,以*进行提领,因而它类似于指针 | Function object(函数对象) | 1、一个行为类似函数的对象,它可以没有参数,也可以带有若干参数。2.重载了调用运算符operator()的类的对象都满足函数对象的特征 3、STL中也定义了一些标准的函数对象,如果以功能划分,可以分为算术运算、关系运算、逻辑运算三大类。为了调用这些标准函数对象,需要包含头文件 | Allocator(分配器) | 负责空间配置与管理。从实现的角度来看,配置器是一个实现了动态空间配置、空间管理、空间释放的class template。 |
3.STL的缺陷
- STL库的更新太慢了。这个得严重吐槽,上一版靠谱是C++98,中间的C++03基本一些修订。C++11出
来已经相隔了13年,STL才进一步更新。 - STL现在都没有支持线程安全。并发环境下需要我们自己加锁。且锁的粒度是比较大的。
- STL极度的追求效率,导致内部比较复杂。比如类型萃取,迭代器萃取。
- STL的使用会有代码膨胀的问题,比如使用vector/vector/vector这样会生成多份代码,当然这是模板语
法本身导致的。
2.string
1.string的简单了解
1. string是表示字符串的字符串类
-
string类是basic_string模板类的一个实例,它使用char来实例化basic_string模板类 -
string在底层实际是: basic_string模板类的别名,typedef basic_string<char, char_traits, allocator> string;  
如何对stl的查阅
对stl的学习,我们需要掌握30%左右的接口函数,剩下的接口函数很少用,不需要记住,当我们需要去使用时,再去查阅,那么我们应该怎么去查阅这些接口函数,首先,我们给出两个网站: 一个是c++官网:https://en.cppreference.com/w/,它支持最新的语法,但它的界面比较乱  另一个是:http://www.cplusplus.com/reference/string/string/string/,它不是官网,它支持c++98和c++11,它的界面比较整洁和规范,容易看,所以推荐使用这个网站去查阅stl。下面我也会介绍怎样去查阅。下面我们以查string为例子:   
然后我们随便点一个接口函数:  
 
2. string常用接口说明
1.string类 对象常见的构造
 
2.string类对象的容量操作

void test
{
string s1("hello world");
cout << s.size() << endl;
cout << s.capacity() << endl;
s1.resize(20, 'x');
s1.resize(5);
s1.clear();
string s2;
s2.resize(20);
string s3;
s3.reserve(20);
}
总结;
-
size()与length()方法底层实现原理完全相同,引入size()的原因是为了与其他容器的接口保持一 致,一般情况下基本都是用size(); -
clear()只是将string中有效字符清空,不改变底层空间大小。 -
resize在改变元素个数时,如果是将元素个数增多,可能会改变底层容量的大 小,如果是将元素个数减少,底层空间总大小不变。 -
reserve(size_t res_arg=0):为string预留空间,不改变有效元素个数,当reserve的参数小于 string的底层空间总大小时,reserver不会改变容量大小。
3. string类对象的访问及遍历操作
 

 总结: 1.[begin(),end()) end()返回的是最后一个字符的下一个位置,c++中凡是给迭代器一般都是给的[)左闭右开的区间。
2.迭代器是类似指针一样的东西,迭代器以++进行累进,以*进行提领。
3.迭代器的意义:像string,vector支持[]遍历,但是list,map等等容器不支持[],迭代器能够使遍历的方式统一
4.迭代器是可读可写。const_iterator const对象 只能读不能写,const对象只能用const_iterator
4. string类对象的修改操作

void test
{
string s1;
s1.push_back('h');
s1.push_back('e');
s1.push_back('l');
s1.push_back('1');
s1.push_back('o');
cout << s1 << endl;
s1.append("world");
cout << s1 << endl;
s1.append(s2);
cout << s1 << endl;
s1 += ' ';
s1 += "sjp";
s1 += s2;
cout << s1 << endl;
s1.insert(4," ");
cout << s1 << endl;
s1.erase(0, 3);
s1.erase(3);
s1.erase();
string filename1("test.cpp");
size_t pos1 = filename1.find('.');
if (pos1 != string::npos)
{
string suff(filename, pos1);
cout << suff << endl;
}
string filename2("test.a.cpp");
size_t pos2=filename2.rfind('.');
if (pos2 != string::npos)
{
string suff(filename, pos2);
cout << suff << endl;
}
}
获取一个网址的协议名和域名 
string GetProtocol(const string& ur1)
{
size_t pos = ur1.find("://");
if (pos != string::npos)
{
return ur1.substr(0, pos);
}
else
{
return string();
}
}
string GetDomain(const string& ur1)
{
size_t pos = ur1.find("://");
if (pos != string::npos)
{
size_t start = pos + 3;
size_t end=ur1.find("/",start);
if (end != string::npos)
{
return ur1.substr(start,end-start);
}
else
{
return string();
}
}
}
int main()
{
string s1 = "https://daohang.qq.com/?fr=hmpage";
string s2 = "http://www.cplusplus.com/reference/string/string/string/";
cout<<GetProtocol(s1)<<endl;
cout<< GetDomain(s1) <<endl;
cout<<GetProtocol(s2)<<endl;
cout<<GetDomain(s2)<<endl;
return 0;
}
输出结果为: 
注意:
- 在string尾部追加字符时,s.push_back? / s.append(1, c) / s += 'c’三种的实现方式差不多,一般
情况下string类的+=操作用的比较多,+=操作不仅可以连接单个字符,还可以连接字符串。 - 对string操作时,如果能够大概预估到放多少字符,可以先通过reserve把空间预留好。
- 尽量少用insert,erase,因为底层实现是数组,头部或者中间要挪动数据,效率太低了。
感谢你的点赞和关注,收藏!!!! 
|