STL源码剖析总结_第八章配接器
三十分钟掌握STL-教程 - 用于合并

三十分钟掌握 STL-教程 教程发布:dxy 字体:[增加 减小] 类型:转载三十分钟掌握 STL 这是本小人书。
原名是《using stl》,不知道是谁写的。
不过我 倒觉得很有趣,所以化了两个晚上把它翻译出来。
我没有对翻译出来的内容校验过。
如果你没法在三十分钟内觉得有所收获,那么赶紧扔了它。
文中我省略了很多东西。
心疼 那,浪费我两个晚上。
译者:kary contact:karymay@ STL 概述 STL 的一个重要特点是数据结构和算法的分离。
尽管这是个简单的概念,但这种分离确实 使得 STL 变得非常通用。
例如,由于 STL 的 sort()函数是完全通用的,你可以用它来操作几乎任何数据集合,包括 链表,容器和数组。
要点 STL 算法作为模板函数提供。
为了和其他组件相区别,在本书中 STL 算法以后接一对圆括弧的方式表示,例如 sort()。
STL 另一个重要特性是它不是面向对象的。
为了具有足够通用性,STL 主要依赖于模板而不是封装,继承和虚函数(多态性)——O OP 的三个要素。
你在 STL 中找不到任何明显的类继承关系。
这好像是一种倒退,但这正好是使得 STL 的组件具有广泛通用性的底层特征。
另外,由于 STL 是基于模板,内联函数的使用使得生成的代码短小高效。
提示: 确保在编译使用了 STL 的程序中至少要使用-O 优化来保证内联扩展。
STL 提供了大量的模板类和函数,可以在 OOP 和常规编程中使用。
所有的 STL 的大约 50 个算法都是完全通用的,而且不依赖于任何特定的数据类型。
下面的小节说明了三个基本的 STL 组件: 1) 迭代器提供了访问容器中对象的方法。
例如,可以使用一对迭代器指定 list 或 vecto r 中的一定范围的对象。
迭代器就如同一个指针。
事实上,C++的指针也是一种迭代器。
但 是,迭代器也可以是那些定义了 operator*()以及其他类似于指针的操作符地方法的类对 象。
《STL源码剖析》读后感

《STL源码剖析》读后感读了这本书后,对StL的知识有了深入的了解,以前觉得神秘、遥远的StL变得清晰可见!本书主要以SgIStL为标准讲解,并未标准的StL。
StL主要是以模板为基础,实现了强大的泛型功能,只要传给其满足规则的参数,即可实现对各种自定义类型的操作。
StL主要包括空间配置器、迭代器、序列容器、关联容器、泛型算法、仿函数、配接器等。
空间配置器负责为对象分配内存、管理内存的使用。
迭代器是一种smartpointer,是连接容器和算法的桥梁。
迭代器类需要实现很多指针的操作符功能。
StL 有五种类型的迭代器,只有遵循这五种标准才可以和算法无缝连接。
序列式容器有vector、list、deque、stack、queue、heap等,容器内部需要有自己的迭代器,需要由空间配置器来分配管理内存,实现一系列添加、删除、查找等操作。
deque是一种双向开口的数据类型,stack 和queue的底层容器就是deuqe,只是关闭了某些操作,完成了堆栈和队列的数据结构。
heap在取出数据的时候一定是从优先级最高的数据开始的,其底层是一个vector结合一个完全二叉树,就实现了优先取优先级高的数据。
关联式容器有set、map、multiset、multimap、hash_set、hash_map、hash_multiset、hash_multimap。
前四个的底层机制是树结构,准确的说是红黑树(RB-tree)。
后四个的底层机制是hashtable(散列表),三类表是一种。
关联容器没有头尾,而是按照键值放到合适的位置,查询键值是必须具有良好的搜寻效率。
关联容器内部结构是一个平衡二叉搜索树,为了防止数据放入树时的不够随机造成的树不平衡而影响搜索效率,需要由算法调整树的结构,保持树的平衡。
实现平衡二叉搜索树的有AvL-tree,RB-tree,AA-tree,AvL-tree里面有单旋转和双旋转算法,后面两个树没怎么了解。
STL源码 侯捷注释

STL源码侯捷注释《STL源码侯捷注释》是一本经典的程序员必备书籍,它为广大程序员提供了深入了解STL源码的机会。
本文将从以下几个方面进行分析和评价。
一、作者介绍侯捷是一位著名的程序员和作家,他曾获得多项国际和国内大奖,包括ACM国际程序设计竞赛金牌、IBM杰出软件奖、国家自然科学二等奖等。
他还是多本计算机书籍的作者,如《STL源码剖析》、《C++程序设计》等。
二、书籍概述《STL源码侯捷注释》是一本详细介绍STL源码的书籍,它对STL的各个组成部分进行了详细的解析和注释。
本书的主要特点包括:1.详细的注释:本书对STL源码的每个细节都进行了详细的解释和注释,使读者能够深入了解STL的实现原理。
2.清晰的结构:本书按照STL源码的结构进行组织,并提供了详细的目录和索引,方便读者查找和理解。
3.丰富的例子:本书提供了大量的例子,帮助读者更好地理解STL的使用方法和实现原理。
4.全面的覆盖:本书覆盖了STL的所有组成部分,包括容器、迭代器、算法、仿函数等。
三、书籍优点1.深入浅出:本书的注释和解释非常详细,但又不失深入浅出的风格,使读者能够轻松理解STL的实现原理。
2.丰富的例子:本书提供了大量的例子,使读者能够更好地理解STL的使用方法和实现原理。
3.清晰的结构:本书按照STL源码的结构进行组织,并提供了详细的目录和索引,方便读者查找和理解。
4.全面的覆盖:本书覆盖了STL的所有组成部分,包括容器、迭代器、算法、仿函数等。
四、书籍不足之处1.过于复杂:本书注释和解释的内容非常详细,但有时候可能会让读者感到过于复杂和深入,不太适合初学者。
2.缺少实战案例:本书提供了大量的例子,但是缺少实战案例,读者可能需要自己去实践。
五、适合读者群体《STL源码侯捷注释》适合以下读者群体:1.对STL源码有兴趣的程序员。
2.希望深入了解STL实现原理的程序员。
3.希望提高自己的STL编程能力的程序员。
4.想要更好地掌握C++语言和STL的程序员。
STL源码剖析总结_第二章-空间配置器

2.空间配置器2.1具备次配置力(sub-allocation)的SGI空间配置器SGI含有两个空间配置器类,std::allocator内存分配类符合标准,但是仅仅是对operator new和operator delete简单封装一下而已;其次是SGI特殊的内存分配器std::alloc,其中实现采用了内存池,对于分配大量小容量的对象,可以大大减少内存碎片。
SGI标准的空间配置器std::allocator这是对应的模板内联内存分配函数。
实现起来也很简单,注意这里分配的内存仅仅是一块没有使用的空间而已,在上面并没有构造对象,后面讲解如何在上面构造对象。
模板内联内存释放函数,直接调用全局的operator delete释放对应的内存。
SGI特殊的空间配置器Std::alloc class Foo{…}Foo* pf = new Foo;//配置内存,然后构造对象delete pf;//将对象析构,然后释放内存new的算是包含两个阶段:1)调用::operator new 配置内存2)调用Foo::Foo()构造对象内容Delete算式也包含两个阶段1)调用Foo::~Foo()将对象析构2)调用::operator delete释放内存为了精密分工,STL allocator将两个阶段的操作分开来,内存配置操作由alloc::allocate()负责,内存释放操作由alloc::deallocate()负责;对象构造由::construct()负责,对象析构由::destroy()负责。
2.stl_alloc.h 内存空间的分配和释放内部使用malloc在堆中申请内存,其中制造了一个内存池,可以减少小型区块过多而造成的内存碎片问题。
SGI设计了双层级配置器,第一级配置器直接使用malloc()和free(),第二级配置器则视情况采用不同的策略:当配置区块超过128bytes时,采用第一级配置器,当配置区块小于128bytes时,采用第二级配置器,采用复杂的memory pool。
C++_STL标准入门汇总

#include <iostream> #include <vector> using namespace std; int main(){
vector<int>vi; int a; while(true) { cout<<"输入一个整数,按0停止输入:"; cin>>a; if(a==0) break; vi.push_back(a); vector<int>::iterator iter; for(iter=vi.begin();iter!=vi.end();++iter) cout<<*iter; } return 0; }
int _i; public: f_c(int i):_i(i){
} void operator()(m_iip::value_type ite) { cout<<_i++<<"\t"<<ite.first<<" shi"<<endl; } void operator()(m_icp::value_type ite) { cout<<_i++<<"\t"<<ite.first<<" yang"<<endl; } }; void f(int i,int c) {
#include <iostream> #include <list> #include <numeric>
#include <algorithm> using namespace std; //创建一个list容器的实例LISTINT typedef list<int> LISTINT;
STL源码剖析学习笔记

STL源码剖析学习笔记
deque的迭代器
deque的迭代器除了⼀些型别定义,主要有以下四个数据成员:
typedef T** map_pointer;
T* cur;
T* first;
T* last;
map_pointer node;
deque的主要的数据成员:
protected:
iterator start;
iterator finish;
map_iterator map;
size_type map_size;
可以看到deque维护了两个迭代器。
迭代器的node指向连续空间map某⼀个元素,first和last指向某个缓冲区的起始和结束,⽽cur指向当前元素。
deque的两个迭代器的cur有特别意义,start.cur指向第⼀个缓冲区的第⼀个元素的位置,finish.cur指向最后缓冲区的最后⼀个元素的位置。
所以两个迭代器的first,last和node很可能完全⼀样(同⼀个缓冲区),cur才是区分他们的根本。
⽽迭代器其实提供给外界的假象就是它是⼀个连续空间,iterator的⾏为就像是cur的⾏为。
所以iterator ite,在++时,只需把cur++即可;在两个迭代器相减时只需把两者的cur 相减;⽐较两个迭代器是否相等时,只需看⼆者cur是否相等,当然,以上的⼤前提是⼀定要考虑是否跨缓冲区间!即迭代器默默维护的first,last,node。
要注意的是start和finish元素增长的⽅向是相反的,⼀个是last---->first,⼀个是first----->last。
STL在《算法设计与分析》课程中的应用

The Application of STL in the Course of Algorithm Design and Analysis
ZHANG Tianwu, WU Qihang
(College of Computer, Henan University of Engineering, Xinzheng, China, 451191)
与解决问题的能力,使学生能够理解经典算法的基 Musser等人设计的一套软件的总称。因为这些软件
本思想,并能将所学算法进行灵活应用,真正解决 实际问题。然而该课程不但内容枯燥抽象,而且要
的高质量和高可靠性,它们被陆续收入到C++标 准库之中[4]。随着计算机技术的发展,STL的应用
求学生具有较强的编程能力,因此,对于一般的普 越来越广泛。STL包括大量数据结构和常用算法,
(4) 强调实验和动手能力的培养:算法讲解不 仅包含思路描述,而且以 C/C++完整源代码呈现,
不再是简单的伪代码描述,同时给出了大量的上机 实验题和在线编程题,大部分是国内外的著名 IT 企业面试题和 ACM 竞赛题,这是很多传统教材所 不能比拟的。
4 课堂教学
STL 应用于《算法设计与分析》的教学,非常 方便,但是 STL 包含内容很多,要想全部熟练掌握 STL 绝非易事,只要在教学过程中根据具体算法内 容讲解相关 STL 内容,大部分学生都能很快掌握利 用基本的 STL 技术进行编程。
比如使用 STL 中的 sort 算法实现整数型数组 b 的递增排序相关代码如下:
#include<iostream> #include <algorithm> using n,7,9,2,5,4,1,3,6,8};
STL源码剖析——deque的实现原理和使用方法详解

STL源码剖析——deque的实现原理和使用方法详解deque(双端队列)是一种支持随机访问的数据结构,可以在队列两端进行插入和删除操作。
STL中的deque实现原理比较复杂,主要采用了分块连续存储的方式。
deque的底层数据结构由多个连续的块组成,每个块大小为固定的值,默认为512个元素。
每个块中的元素存储在一个连续的内存区域中,块与块之间通过一个指针链表连接起来。
deque的内部结构包含了一组指向块的指针,以及指向块内部元素的指针。
deque支持随机访问,可以通过指针直接访问指定位置的元素,时间复杂度为O(1)。
deque在插入和删除操作时需要考虑位置的前后情况。
若插入位置在deque的前半段,即与deque的起始位置的距离小于等于deque大小的一半,此时从deque的起始位置向前遍历,找到离插入位置最近的块,并在该块内完成插入操作。
同理,若插入位置在deque的后半段,则从deque的末尾位置开始向后遍历。
deque的插入和删除操作都需要涉及到内存的扩容和迁移,以保证数据的连续性。
当deque的容量不足时,会重新分配一块更大的内存空间,并将之前的数据迁移到新的内存空间中。
这一过程需要考虑到deque内部的指针和迭代器的更新。
deque的使用方法比较简单,可以通过#include <deque>来引入deque类的定义。
使用deque时需要注意以下几点:- 可以使用push_back(和push_front(函数向deque中插入元素,分别在队尾和队头插入。
- 使用pop_back(和pop_front(函数可以删除deque中的元素,分别删除队尾和队头的元素。
- 通过[]操作符可以随机访问deque中的元素。
- 使用size(函数可以获得deque中元素的个数。
- 使用clear(函数可以清空deque中的所有元素。
需要注意的是,deque由于采用了分块连续存储的方式,对于插入和删除操作的时间复杂度为O(1)。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
8 配接器
8.1 配接器之概观与分类
1、设计模式中对配接器的定义如下:将一个class的接口转换为另一个class的接口,使原本因接口不兼容而不能合作的classes可以一起运作。
2、容器配接器(应用于容器)
stack和queue是两个容器配接器,底层默认由deque构成。
stack封住了所有的deque对外接口,只开放符合stack原则的几个函数;queue封住了所有的deque 对外接口,只开放符合queue原则的几个函数。
3、迭代器配接器(应用于迭代器)
3.1 insert iterators
可以把一般迭代器的复制操作转变为插入操作。
insert iterators包括back_insert_iterator(专门负责尾端插入),front_insert_iterator (专门负责头端插入)和insert_iterator(可以负责任何位置执行插入)。
主要观念是,每个insert iterators内部都维护有一个容器;容器有自己的迭代器,当客户端对insert iterators做赋值操作时,就在insert iterators中转为对该容器的迭代器做插入操作,其他的迭代器功能则被关闭。
3.2 reverse iterators
reverse iterators将迭代器的行进方向逆转,使原本应该前进的operator++变成了后退操作,原本后退的operator—操作变成了前进操作。
当迭代器被逆转,虽然实体位置不变,但逻辑位置必须改变,主要是为了配合迭代器区间的“前闭后开“习惯。
3.3 IOStream iterators
IOStream iterators可以将迭代器绑定到某个iostream对象身上。
绑定一个istream object(例如:std::cin),称为istream_iterator,拥有输入功能。
绑定到ostream object (例如:std::cout),称为ostream_iteratpr,拥有输出功能。
内部维护一个istream member,客户端对这个迭代器做的operator++操作,会被导引调用内部所含的那个istream member的输入操作。
绑定一个ostream object,就是在ostream iterator内部维护一个ostream member,客户端对这个迭代器做的operator=操作,会被导引调用内部所含的那个ostream member的输出操作。
3.4 运用实例
4、仿函数配接器
仿函数配接操作包括绑定(bind)、否定(negate)、组合(compose)、以及对一般函数或成员函数的修饰。
仿函数配接器的价值在于,通过它们之间的绑定、组合、修饰能力,几乎可以创造出各种可能的表达式,配合STL算法。
每一个仿函数配接
器内藏了一个member object,其型别等同于它所要配接的对象。
运用实例
1)对返回值进行逻辑否定:not1,not2
2)对参数进行绑定:bind1st,bind2nd
3)用于函数合成:compose1,compose2
compose1是h(x)=f(g(x)), compose2是h(x)=f(g1(x),g2(x))
举例:
4)用于函数指针:ptr_fun
将一般函数当作仿函数使用。
举例:
5)用于成员函数指针:mem_fun,mem_fun_ref
运用实例。