1、STL的代码从广义上来说,分为三类:algorithm(算法),container(容器),和iterator(迭代器),几乎所有的代码都采用了模板类和模板函数的方式,这相比传统的由函数和类组成的苦来说提供了更好的重用机会,在C++标准中,STL被组织为下面的13个头文件:<algotithm>,<deque>,<functional>,<iterator>,<vector>,<list>,<map>,<memory>,<numertic>,<queue>,<set>,<stack>,<utility>
STL的代码从广义上来讲分为三类:algorithm(算法),container(容器),iterator(迭代器),几乎所有的代码都采用了模板类和模板函数的方式,这笔传统方式的函数和类组成的哭来说提供了跟好的重用机会
2、算法:
STL中提供了 大约100个实现算法的模板函数,比如算法for_each将为执行序列中的每一个元素调用指定的函数,stable_sort以你所指定的规划对序列进行稳定性排序等等。这样一来,只要我们熟悉了STL之后,许多代码可以被大大的化简,只需要通过调用一个俩个算法模板,就可以完成所需要的功能并且大大提高效率。
算法部分主要由头文件<algorithm>,<numeric>和<functional>组成。
<algorithm>是所有STL头文件中最大的一个(尽管它很好理解),它是由一大堆模版函数组成的,可以认为每个函数在很大程度上都是独立的,其中常用到的功能范围涉及到比较、交换、查找、遍历操作、复制、修改、移除、反转、排序、合并等等。
<numeric>体积很小,只包括几个在序列上面进行简单数学运算的模板函数,包括加法和乘法在序列上的一些操作。
<functional>中则定义了一些模板类,用以声明函数对象。
3、容器:
在实际开发中,数据结构本身的重要性不会须臾操作与数据结构的算法的重要性,当程序中存在着对时间要求很高的部分时候,数据结构的选择就更加重要。
容器部分主要由头文件<vector>,<list>,<deque>,<set>,<map>,<stack>和<queue>组成。对于常用的一些容器和容器适配器(可以看作由其它容器实现的容器),可以通过下表总结一下它们和相应头文件的对应关系。
二、基本思想:STL是一个功能强大的可扩展的工具集,用来组织和处理数据。为了最大限度地满足各种类型数据的需求,这个工具集全部由模板定义。(1)容器库(container library):定义了管理和存数据的容器。这个库的模板被定义咋array,vector,stack,queue,deque,list,forward_list,set,map。(2)迭代器库(iterator library):定义了迭代器,迭代其实是类似于指针的对象,通常被用于引用容器类的对象序列。这个库被定义在单个头文件algorithm。(3)容器适配器(container adapters):是提供了替换机制的适配类模板,可以用来访问基础的序列容器或关联容器。除非对象是右值-临时对象,一种有临时语义的类型,否则所有的STL中存放的都是对象的副本。注意:不要再以基类为元素的容器中存放派生类,这将会导致派生类对象的切片。如果想在容器中访问派生类,则需要使用多肽。也就是说在存储基类指针或几类智能指针的容器中存储派生类指针。
4、迭代器:是一个行为类似于指针的模板类对象。只要迭代器iter指向了一个有效对象,就可以通过*iter解引用的方式,来获取一个对象的使用。如果iter指向一个可以访问成员的类对象,类成员就可以通过iter->member来使用。所以,使用迭代器就像使用指针。当要以某种方式处理容器的元素时候,可以通过使用迭代器来访问他们,尤其是要使用STL算法时候,迭代器将算法和不同类型容器的元素联系起来。迭代器将算法和数据源分离出来,算法不需要知道数据来源于容器。迭代器是一个定义在iterator头文件中的模板类型实例。算法不需要知道数据来源于容器。
通常会使用一对迭代器来定义一段元素,这些元素可能是容器中的对象,伙食标准数组中的元素,或是字符串中的字符,总而言之,可以是任何支持迭代器的对象元素。
5、获取迭代器:迭代器允许以一种逐步自增的方式从一个元素移到另一个元素。有俩个全局函数,cbegin(),cend(),可以返回数组。容器或字符串对象的常量迭代器。记住,常量迭代器指向的是一个常量,但是任然可以修改这个迭代器本身的值。
6、迭代器的种类:拷贝构造,析构,拷贝复制。迭代器指向的对象必须时刻交换的;5种类型的迭代器分别反映了他们不同层次的功能。一个容器能偶或去什么类型的迭代器,取决于这个容器的类型。算法可以通过传入的迭代器的参数类别,来判断迭代器具有什么样的功能。一次列出不容类别的迭代器:
(1)输入迭代器(input iterator):提供对对象的只读访问。如果是输入迭代器,必须支持*iter以引用他所指向的值。输入迭代器只能单个使用,这就意味着迭代起自增之后,只能通过使用新的迭代器来访问上一个他所指向的元素。每次想访问一个序列时候就需要创建一个新的迭代器。可以对输入迭代器做这些操作:++iter或者iter++,iter1 == iter2 和 iter1!=iter2 。需要注意的是,*iter 并没有减量操作,可以在输入迭代器上使用iter->member操作。
(2)输出迭代器:提供对对象的只写访问。输出迭代器是只写的不能提供iter->member 这样的操作。
(3)正向迭代器:结合了输入输出迭代器,可以多次对他进行读写操作。
(4)双向迭代器:具有正向迭代器所有的功能,但允许前向和后向遍历。因此可以自增来移动到另外一个元素,也可以使用前缀的自减来移动到另外一个元素。
(5)随机访问迭代器:提供了和双向迭代器同样的功能,能支持杜元素的随机访问。iter+n,iter+=n等操作,iter[n] == *(iter+n),俩个迭代器的比较 iter1<iter2,俩个迭代器之间的差异iter1-iter2 得到俩个迭代器之间的元素的个数。
迭代器的特定取决于他来自容器的类型。vector,deque提供了随机访问迭代器。
直接包含iterator是多余的,因为在容器的头文件中都包含了iterator。
7、迭代器适配器:是一个类模板,它为标准迭代器提供了一些特殊的行为,他使得他们能够对迭代器模板得到派生。适配器类模板定义了三种不同的迭代器:反向迭代器,插入迭代器,移动迭代器
(1)反向迭代器:可以想使用随机访问迭代器一样,使用反向随机迭代器进行下表操作,效果是相反的。基础迭代器总是指向反向迭代器下一个位置。
(2)插入迭代器:插入迭代器用于在容器任何位置添加新的元素。后向插入迭代器push_back(),前向插入迭代器,front_insert_iterator,插入迭代器:insert_iterator,想任何有insert()函数的容器中插入一个新的元素。
8、迭代器上的运算:(1)advanc(iter,n);将迭代器iter向前移动了n个元素(2)distence(iter1,iter2)返回俩个迭代器之间的元素个数作为返回值。
(3)next(iter,n)next可以得到iter正向偏移n之后所指向位置的一个迭代器。迭代器iter必须是具有真相迭代器能力的迭代器。(4)preev(iter,n)prev返回iter反向偏移n之后所指向位置的迭代器。迭代器必须是具有双向迭代器功能的迭代器。
9、智能指针:智能指针是一个可以模仿原生指针的模板类。