STL标准模板库概述

 

1.组成部分

STL提供六大组件彼此此可以组合套用:

1、容器

容器就是各种数据结构,我就不多说,看看下面这张图回忆一下就好了,从实现角度看,STL容器是一种class template。




1.vector:底层数据结构为数组 ,支持快速随机访问。
2.list:底层数据结构为双向链表,支持快速增删。
3.deque:底层数据结构为一个中央控制器和多个缓冲区,详细见STL源码剖析P146,支持首尾(中间不能)快速增删,也支持随机访问。
4.stack:底层一般用23实现,封闭头部即可,不用vector的原因应该是容量大小有限制,扩容耗时
5.queue:底层一般用23实现,封闭头部即可,不用vector的原因应该是容量大小有限制,扩容耗时(stack和queue其实是适配器,而不叫容器,因为是对容器的再封装)
6.priority_queue:的底层数据结构一般为vector为底层容器,堆heap为处理规则来管理底层容器实现
7.set:底层数据结构为红黑树,有序,不重复。
8.multiset:底层数据结构为红黑树,有序,可重复。 
9.map:底层数据结构为红黑树,有序,不重复。
10.multimap:底层数据结构为红黑树,有序,可重复。
11.hash_set:底层数据结构为hash表,无序,不重复。
12.hash_multiset:底层数据结构为hash表,无序,可重复 。
13.hash_map :底层数据结构为hash表,无序,不重复。
14.hash_multimap:底层数据结构为hash表,无序,可重复。 
15.unordered_set:底层数据结构为hash表,无序,不重复。
16.unordered_multiset:底层数据结构为hash表,无序,可重复 。
17.unordered_map :底层数据结构为hash表,无序,不重复。
18.unordered_multimap:底层数据结构为hash表,无序,可重复。 

上面看起来好像unorderd_系列和hash_系列是一样的,他俩是什么关系呢?
实际上unorderd_系列是约等于hash_系列的,

最初的 C++ 标准库中没有类似 hash_map 的实现,但不同实现者自己提供了非标准的 hash_map。 因为这些实现不是遵循标准编写的,所以它们在功能和性能保证方面都有细微差别。从 C++ 11 开始,hash_map 实现已被添加到标准库中。但为了防止与已开发的代码存在冲突,决定使用替代名称 unordered_map。这个名字其实更具描述性,因为它暗示了该类元素的无序性。

2、算法

各种常见算法,如sort,search,copy,erase等,我觉得其中比较值得学习的就是sort,next_permutation,partition,merge sort,从实现角度看,STL算法是一种函数模板。

 

3、迭代器

扮演容器与算法之间的胶合剂,是所谓的“泛型指针”。共有五种类型,从实现角度看,迭代器是一种将operator*,operator->,operator++,operator--等指针相关操作予以重载的class template。所有STL容器都附带有自己专属的迭代器,只有容器设计者才知道如何设计迭代器。原生指针也是一种迭代器。是设计模式的一种,所以被问到了解的设计模式可以用来凑数。

 

4、仿函数

仿函数(functor),就是使一个类的使用看上去像一个函数。
其实现就是类中实现一个operator(),
这个类就有了类似函数的行为,就是一个仿函数类了。

 

5、容器配接器

对啊。。。对于使用者来说,没差别。
对于实现而言,配接器是使用已经实现好的容器去提供新的接口,比如stl中的栈的实现,根本就是个接口转发
配接器提供接口更加灵活
比如queue和stack,看着像容器,其实就是deque包了一层皮。

 

6、空间配置器

负责空间配置与管理。从实现角度看,配置器是一个实现了动态空间配置、空间管理、空间释放额class template。

2.相关问题:

如何在共享内存上使用stl标准库?

想像一下把STL容器,例如map, vector, list等等,放入共享内存中,IPC一旦有了这些强大的通用数据结构做辅助,无疑进程间通信的能力一下子强大了很多。我们没必要再为共享内存设计其他额外的数据结构,另外,STL的高度可扩展性将为IPC所驱使。STL容器被良好的封装,默认情况下有它们自己的内存管理方案。当一个元素被插入到一个STL列表(list)中时,列表容器自动为其分配内存,保存数据。考虑到要将STL容器放到共享内存中,而容器却自己在堆上分配内存。一个最笨拙的办法是在堆上构造STL容器,然后把容器复制到共享内存,并且确保所有容器的内部分配的内存指向共享内存中的相应区域,这基本是个不可能完成的任务。

 

假设进程A在共享内存中放入了数个容器,进程B如何找到这些容器呢?一个方法就是进程A把容器放在共享内存中的确定地址上(fixed offsets),则进程B可以从该已知地址上获取容器。另外一个改进点的办法是,进程A先在共享内存某块确定地址上放置一个map容器,然后进程A再创建其他容器,然后给其取个名字和地址一并保存到这个map容器里。进程B知道如何获取该保存了地址映射的map容器,然后同样再根据名字取得其他容器的地址。

发布了61 篇原创文章 · 获赞 17 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/vjhghjghj/article/details/90543576