版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、STL就是Standard Template Library,标准模板库。这可能是一个历史上最令人兴奋的工具的最无聊的术语。从根本上说,STL是一些“容器”的集合,这些“容器”有list, vector,set,map等,STL也是算法和其它一些组件的集合。这里的“容器”和算法的集合指的是世界上很多聪慧人很多年的杰作。是C标准库的一个重要组成部分,它由Stepanov and Lee等人最先开发,它是与C几乎同时开头开发的;一开头STL选择了Ada作为实现语言,但Ada有点不争气,最后他们选择了C,C中已经有了模板。STL又被添加进了C库。1996年,惠普公司又免费公开了STL,为STL的推广
2、做了很大的贡献。STL供应了类型平安、高效而易用特性的STL无疑是最值得C+程序员高傲的部分。每一个C程序员都应该好好学习STL。大体上包括container(容器)、algorithm(算法)和iterator(迭代器),容器和算法通过迭代器可以进行无缝连接。 一、基础知识1、泛型技术泛型技术的实现方法有多种,比如模板,多态等。模板是编译时决定,多态是运行时决定,其他的比如RTTI也是运行时确定。多态是依靠虚表在运行时查表实现的。比如一个类拥有虚方法,那么这个类的实例的内存起始地址就是虚表地址,可以把内存起始地址强制转换成int*,取得虚表,然后(int*)*(int*)取得虚表里的第一个函
3、数的内存地址,然后强制转换成函数类型,即可调用来验证虚表机制。泛型编程(generic programming,以下直接以GP称呼)是一种全新的程序设计思想,和OO,OB,PO这些为人所熟知的程序设计想法不同的是GP抽象度更高,基于GP设计的组件之间偶合度底,没有继承关系,所以其组件间的互交性和扩展性都特别高。我们都知道,任何算法都是作用在一种特定的数据结构上的,最简洁的例子就是快速排序算法最根本的实现条件就是所排序的对象是存贮在数组里面,由于快速排序就是由于要用到数组的随机存储特性,即可以在单位时间内交换远距离的对象,而不只是相临的两个对象,而如果用联表去存储对象,由于在联表中取得对象的时间
4、是线性的即On,这样将使快速排序失去其快速的特点。也就是说,我们在设计一种算法的时候,我们总是先要考虑其应用的数据结构,比如数组查找,联表查找,树查找,图查找其核心都是查找,但由于作用的数据结构不同将有多种不同的表现形式。数据结构和算法之间这样亲密的关系始终是我们以前的生疏。泛型设计的根本思想就是想把算法和其作用的数据结构分离,也就是说,我们设计算法的时候并不去考虑我们设计的算法将作用于何种数据结构之上。泛型设计的抱负状态是一个查找算法将可以作用于数组,联表,树,图等各种数据结构之上,变成一个通用的,泛型的算法。2、四种类型转换操作符static_cast 将一个值以符合规律的方式转换。应用到
5、类的指针上,意思是说它允许子类类型的指针转换为父类类型的指针(这是一个有效的隐式转换),同时,也能够执行相反动作:转换父类为它的子类。例如:float x; Countstatic_cast(x);/把x作为整型值输出 dynamic_cast 将多态类型向下转换为其实际静态类型。只用于对象的指针和引用。当用于多态类型时,它允许任意的隐式类型转换以及相反过程。dynamic_cast会检查操作是否有效。也就是说,它会检查转换是否会返回一个被恳求的有效的完整对象。检测在运行时进行。如果被转换的指针不是一个被恳求的有效完整的对象指针,返回值为NULL. 例如:class Car; class Ca
6、briolet:public Car ; class Limousline:public Car ; void f(Car *cp) Cabriolet *p = dynamic_cast cp; reinterpret_cast 转换一个指针为其它类型的指针。它也允许从一个指针转换为整数类型。反之亦然。这个操作符能够在非相关的类型之间转换。操作结果只是简洁的从一个指针到别的指针的值的二进制拷贝。在类型之间指向的内容不做任何类型的检查和转换。例如:class A ;class B ;A * a = new A;B * b = reinterpret_cast(a); const_cast一般用
7、于强制消除对象的常量性。例如:class C ;const C *a = new C;C *b = const_cast(a);其它三种操作符是不能修改一个对象的常量性的。 3、explicit修饰的构造函数不能担当转换函数。在很多情况下,隐式转换是有意的,并且是正当的。但有时我们不盼望进行这种自动的转换。例如:为了避开这样的隐式转换,应该象下面这样显式声明该带单一参数的构造函数:class String int size;char *p;/.public: / 不要隐式转换 explicit String (int sz); String (const char *s, int size n
8、 = 0); / 隐式转换;void f () String s(10); s = 100; / 现在编译时出错;需要显式转换: s = String(100); / 好;显式转换 s = st; / 好;此时允许隐式转换 4、命名空间namespace 解决在使用不同模块和程序库时,消失名称冲突问题。5、C+标准程序库中的通用工具。由类和函数构成。这些工具包括: 数种通用类型 一些重要的C函数 数值极值 二、STL六大组件容器(Container)算法(Algorithm)迭代器(Iterator)仿函数(Function object)适配器(Adaptor)空间配置器(allocator
9、)1、容器作为STL的最主要组成部分容器,分为向量(vector),双端队列(deque),表(list),队列(queue),堆栈(stack),集合(set),多重集合(multiset),映射(map),多重映射(multimap)。容器特性所在头文件向量vector可以用常数时间访问和修改任意元素,在序列尾部进行插入和删除时,具有常数时间简单度,对任意项的插入和删除就有的时间简单度与到末尾的距离成正比,尤其对向量头的添加和删除的代价是惊人的高的双端队列deque基本上与向量相同,唯一的不同是,其在序列头部插入和删除操作也具有常量时间简单度表list对任意元素的访问与对两端的距离成正比,
10、但对某个位置上插入和删除一个项的花费为常数时间。队列queue插入只可以在尾部进行,删除、检索和修改只允许从头部进行。依据先进先出的原则。堆栈stack堆栈是项的有限序列,并满足序列中被删除、检索和修改的项只能是最近插入序列的项。即依据后进先出的原则集合set由节点组成的红黑树,每个节点都包含着一个元素,节点之间以某种作用于元素对的谓词排列,没有两个不同的元素能够拥有相同的次序,具有快速查找的功能。但是它是以牺牲插入删除操作的效率为代价的多重集合multiset和集合基本相同,但可以支持重复元素具有快速查找能力映射map由键,值对组成的集合,以某种作用于键对上的谓词排列。具有快速查找能力多重集
11、合multimap比起映射,一个键可以对应多了值。具有快速查找能力STL容器能力表: 2、算法算法部分主要由头文件,和组成。是全部STL头文件中最大的一个,它是由一大堆模版函数组成的,可以认为每个函数在很大程度上都是独立的,其中常用到的功能范 围涉及到比较、交换、查找、遍历操作、复制、修改、移除、反转、排序、合并等等。体积很小,只包括几个在序列上面进行简洁数学运算的模板函数,包括加法和乘法在序列上的一些操作。中则定义了一些模板类,用以声明函数对象。STL的算法也是特别优秀的,它们大部分都是类属的,基本上都用到了C的模板来实现,这样,很多相像的函数就不用自己写了,只要用函数模板就可以了。我们使用
12、算法的时候,要针对不同的容器,比如:对集合的查找,最好不要用通用函数find(),它对集合使用的时候,性能特别的差,最好用集合自带的find()函数,它针对了集合进行了优化,性能特别的高。 3、迭代器它的简略实现在中,我们完全可以不管迭代器类是怎么实现的,大多数的时候,把它理解为指针是没有问题的(指针是迭代器的一个特例,它也属于迭代器),但是,决不能完全这么做。迭代器功能输入迭代器Input iterator向前读Reads forwardistream输出迭代器Output iterator向前写Writes forwardostream,inserter前向迭代器Forward itera
13、tor向前读写Read and Writes forward 双向迭代器Bidirectional iterator向前向后读写Read and Writes forward andbackwardlist,set,multiset,map,multimap随机迭代器Random access iterator随机读写Read and Write with randomaccessvector,deque,array,string 4、仿函数仿函数,又或叫做函数对象,是STL六大组件之一;仿函数虽然小,但却极大的拓展了算法的功能,几乎全部的算法都有仿函数版本。例如,查找算法find_if就是对
14、find算法的扩展,标准的查找是两个元素相等就找到了,但是什么是相等在不怜悯况下却需要不同的定义,如地址相等,地址和邮编都相等,虽然这些相等的定义在变,但算法本身却不需要转变,这都多亏了仿函数。仿函数(functor)又称之为函数对象(function object),其实就是重载了()操作符的struct,没有什么特别的地方。如以下代码定义了一个二元推断式functor:struct IntLessbool operator()(int left, int right) const return (left right);为什么要使用仿函数呢?1).仿函数比一般的函数敏捷。2).仿函数有类型
15、识别,可以作为模板参数。3).执行速度上仿函数比函数和指针要更快的。怎么使用仿函数?除了在STL里,别的地方你很少会看到仿函数的身影。而在STL里仿函数最常用的就是作为函数的参数,或者模板的参数。在STL里有自己预定义的仿函数,比如全部的运算符,=,-,*,、比如号的仿函数是lesstemplatestruct less : public binary_function / functor for operator bool operator()(const _Ty& _Left, const _Ty& _Right) const / apply operator to operands re
16、turn (_Left _Right); ;从上面的定义可以看出,less从binary_function继承来的,那么binary_function又是什么的?templatestruct binary_function / base class for binary functions typedef _Arg1 first_argument_type; typedef _Arg2 second_argument_type; typedef _Result result_type;其实binary_function只是做一些类型声明而已,别的什么也没做,但是在STL里为什么要做这些呢?如果
17、你要阅读过STL的源码,你就会发现,这样的用法很多,其实没有别的目的,就是为了便利,平安,可复用性等。但是既然STL里面内定如此了,所以作为程序员你必必要遵循这个规章,否则就别想平安的使用STL。比如我们自己定一个仿函数。可以这样:template class func_equal :public binary_function inline bool operator()(type1 t1,type2 t2) const/这里的const不能少 return t1 = t2;/当然这里要overload= 我们看这一行: inline bool operator()(type1 t1,typ
18、e2 t2) const/这里的const不能少inline是声明为内联函数,我想这里应该不用多说什么什么了,关键是为什么要声明为const的?要想找到缘由还是看源码,加入如果我们这里写一行代码,find_if(s.begin(),s.end(),bind2nd(func_equal(),temp),在bind2nd函数里面的参数是const类型的,const类型的对象,只能访问cosnt修饰的函数!与binary_function(二元函数)相对的是unary_function(一元函数),其用法同binary_functionstruct unary_function typedef _A
19、 argument_type; typedef _R result_type; ;注:仿函数就是重载()的class,并且重载函数要为const的,如果要自定义仿函数,并且用于STL接配器,那么肯定要从binary_function或者,unary_function继承。 5、适配器适配器是用来修改其他组件接口的STL组件,是带有一个参数的类模板(这个参数是操作的值的数据类型)。STL定义了3种形式的适配器:容器适配器,迭代器适配器,函数适配器。容器适配器:包括栈(stack)、队列(queue)、优先(priority_queue)。使用容器适配器,stack就可以被实现为基本容器类型(ve
20、ctor,dequeue,list)的适配。可以把stack看作是某种特别的vctor,deque或者list容器,只是其操作仍然受到stack本身属性的限制。queue和priority_queue与之类似。容器适配器的接口更为简洁,只是受限比一般容器要多。迭代器适配器:修改为某些基本容器定义的迭代器的接口的一种STL组件。反向迭代器和插入迭代器都属于迭代器适配器,迭代器适配器扩展了迭代器的功能。函数适配器:通过转换或者修改其他函数对象使其功能得到扩展。这一类适配器有否定器(相当于非操作)、绑定器、函数指针适配器。函数对象适配器的作用就是使函数转化为函数对象,或是将多参数的函数对象转化为少参
21、数的函数对象。例如:在STL程序里,有的算法需要一个一元函数作参数,就可以用一个适配器把一个二元函数和一个数值,绑在一起作为一个一元函数传给算法。 例如: find_if(coll.begin(), coll.end(), bind2nd(greater (), 42); 这句话就是找coll中第一个大于42的元素。 greater (),其实就是号,是一个2元函数 bind2nd的两个参数,要求一个是2元函数,一个是数值,结果是一个1元函数。bind2nd就是个函数适配器。 6、空间配置器STL的内存配置器在我们的实际应用中几乎不用涉及,但它却在STL的各种容器背后悄悄做了大量的工作,STL
22、内存配置器为容器安排并管理内存。统一的内存管理使得STL库的可用性、可移植行、以及效率都有了很大的提升。SGI-STL的空间配置器有2种,一种仅仅对c语言的malloc和free进行了简洁的封装,而另一个设计到小块内存的管理等,运用了内存池技术等。在SGI-STL中默认的空间配置器是其次级的配置器。SGI使用时std:alloc作为默认的配置器。A)alloc把内存配置和对象构造的操作分开,分别由alloc:allocate()和:construct()负责,同样内存释放和对象析够操作也被分开分别由alloc:deallocate()和:destroy()负责。这样可以保证高效,由于对于内存安
23、排释放和构造析够可以依据简略类型(type traits)进行优化。比如一些类型可以直接使用高效的memset来初始化或者忽视一些析构函数。对于内存安排alloc也供应了2级安排器来应对不怜悯况的内存安排。B)第一级配置器直接使用malloc()和free()来安排和释放内存。其次级视情况接受不同的策略:当需求内存超过128bytes的时候,视为足够大,便调用第一级配置器;当需求内存小于等于128bytes的时候便接受比较简单的memeory pool的方式管理内存。C)无论allocal被定义为第一级配置器还是其次级,SGI还为它包装一个接口,使得配置的接口能够符合标准即把配置单位从byte
24、s转到了元素的大小: templateclass simple_allocpublic: static T* allocate(size_t n) return 0 = n ? 0 : (T*)Alloc:allocate(n * sizeof(T); static T* allocate(void) return (T*) Alloc:allocate(sizeof(T); static void deallocate(T* p, size_t n) if (0 != n) Alloc:deallocate(p, n * sizeof(T); static void deallocate(T
25、* p) Alloc:deallocate(p, sizeof(T); d)内存的基本处理工具,它们均具有commt or rollback能力。templateForwardIteratoruninitialized_copy(InputIterator first, InputIterator last, ForwardIterator result); templatevoid uninitialized_fill(ForwardIterator first, ForwardIterator last, const T& x); templateForwardIteratoruninit
26、ialized_fill_n(ForwardIterator first, ForwardIterator last, const T& x) 三、简略容器、算法1、全部容器都供应了一个默认的构造函数,一个拷贝构造函数。例如:list l;.vector ivector(l.begin(),l.end(); int array=1,2,3,4;.set iset(array,array+sizeof(array)/sizeof(array0); 2、与大小相关的函数size(),empty(),max_size()3、返回迭代器的函数begin(),end(),rbegin(),rend()4
27、、比较操作=,!=,=. Vector详解:capacity(),返回vector能够容纳的元素个数。size(),返回vector内现有元素的个数。赋值操作:c1=c2; 把c2的全部元素指派给c1c.assign(n,elem);复制n个elem,指派给cc.assign(beg,end);将区间beg,end内的元素指派给cc1.s);将c1,c2元素互换s);同上元素存取c.at(index);cindex;c.front();返回第一个元素c.back(); 插入和删除:c.insert(pos.elem);c.insert(pos,n.elem); 插入n个elemc.insert
28、(pos,beg,end); 在pos出插入beg,end区间内的全部元素。c.push_back(elem);c.pop_back();c.erase(pos); 删除pos上的元素,返回下一个元素c.erase(beg,end);c.resize(num);将元素数量改为num,如果size变大了,多出来的新元素都要一default方式构建。c.resize(num,elem);将元素数量改为num,如果size变大了,多出来的新元素是elem的副本。c.clear();删除全部。 vector的reserve和resizereserve只安排空间,而不创建对象,size()不变。而res
29、ize安排空间而且用空对象填充.reserve是容器预留空间,但并不真正创建元素对象,在创建对象之前,不能引用容器内的元素,因此当加入新的元素时,需要用push_back()/insert()函数。resize是转变容器的大小,并且创建对象,因此,调用这个函数之后,就可以引用容器内的对象了,因此当加入新的元素时,用operator操作符,或者用迭代器来引用元素对象。再者,两个函数的形式是有区分的,reserve函数之后一个参数,即需要预留的容器的空间;resize函数可以有两个参数,第一个参数是容器新的大小,其次个参数是要加入容器中的新元素,如果这个参数被省略,那么就调用元素对象的默认构造函数
30、。vector有而deque无的:capacity(), reserve();deque有而vector无的:push_front(elem), pop_front(); push_back(elem), pop_back();STL供应的另两种容器queue、stack,其实都只不过是一种adaptor,它们简洁地修饰deque的界面而成为另外的容器类型 List详解:for_each (.begin(), .end(), “函数”);count (.begin(), .end(), 100, jishuqi);返回对象等于100的个数jishuqi值。count_if() 带一个函数对象的
31、参数(上面“100”的这个参数)。函数对象是一个至少带有一个operator()方法的类。这个类可以更简单。find(*.begin().*end(),“要找的东西”);如果没有找到指出的对象,就会返回*.end()的值,要是找到了就返回一个指着找到的对象的iteratorfine_if();与count_if()类似,是find的更强大版本。STL通用算法search()用来搜寻一个容器,但是是搜寻一个元素串,不象find()和find_if() 只搜寻单个的元素。search算法在一个序列中找另一个序列的第一次消失的位置。search(A.begin(), A.end(), B.begin
32、(), B.end();在A中找B这个序列的第一次消失。要排序一个list,我们要用list的成员函数sort(),而不是通用算法sort()。list容器有它自己的sort算法,这是由于通用算法仅能为那些供应随机存取里面元素 的容器排序。list的成员函数push_front()和push_back()分别把元素加入到list的前面和后面。你可以使用insert() 把对象插入到list中的任何地方。insert()可以加入一个对象,一个对象的若干份拷贝,或者一个范围以内的对象。list成员函数pop_front()删掉list中的第一个元素,pop_back()删掉最后一个元素。函数era
33、se()删掉由一个iterator指出的元素。还有另一个erase()函数可以删掉一个范围的元素。list的成员函数remove()用来从list中删除元素。*.remove(要删除的对象);通用算法remove()使用和list的成员函数不同的方式工作。一般情况下不转变容器的大小。remove(*.begin(),*.end(),要删除的对象);使用STL通用算法stable_partition()和list成员函数splice()来划分一个list。stable_partition()是一个有味的函数。它重新排列元素,使得满足指定条件的元素排在不满足条件的元素前面。它维持着两组元素的挨次关
34、系。splice 把另一个list中的元素结合到一个list中。它从源list中删除元素。 Set Map详解:STL map和set的使用虽不简单,但也有一些不易理解的地方,如:为何map和set的插入删除效率比用其他序列容器高?为何每次insert之后,以前保存的iterator不会失效?为何map和set不能像vector一样有个reserve函数来预安排数据?当数据元素增多时(10000到20000个比较),map和set的插入和搜寻速度变化如何?C+ STL中标准关联容器set, multiset, map, multimap内部接受的就是一种特别高效的平衡检索二叉树:红黑树,也成为
35、RB树(Red-Black Tree)。RB树的统计性能要好于一般的平衡二叉树(AVL-树).为何map和set的插入删除效率比用其他序列容器高?大部分人说,很简洁,由于对于关联容器来说,不需要做内存拷贝和内存移动。说对了,确实如此。map和set容器内全部元素都是以节点的方式来存储,其节点结构和链表差不多,指向父节点和子节点。这里的一切操作就是指针换来换去,和内存移动没有关系。为何每次insert之后,以前保存的iterator不会失效?(同解)为何map和set不能像vector一样有个reserve函数来预安排数据?究其原理来说时,引起它的缘由在于在map和set内部存储的已经不是元素本
36、身了,而是包含元素的节点。其实你就记住一点,在map和set内面的安排器已经发生了变化,reserve方法你就不要奢望了。当数据元素增多时(10000和20000个比较),map和set的插入和搜寻速度变化如何?如果你知道log2的关系你应该就彻底了解这个答案。在map和set中查找是使用二分查找,也就是说,如果有16个元素,最多需要比较4次就能找到结果,有32个元素,最多比较5次。那么有10000个呢?最多比较的次数为log10000,最多为14次,如果是20000个元素呢?最多不过15次。 泛型算法:全部算法的前两个参数都是一对iterators:first,last),用来指出容器内一个
37、范围内的元素。每个算法的声明中,都表现出它所需要的最低层次的iterator类型。 常用算法:accumulate() 元素累加adjacent_difference() 相邻元素的差额adjacent_find() 搜寻相邻的重复元素binary_search() 二元搜寻copy() 复制copy_backward() 逆向复制count() 计数count_if() 在特定条件下计数equal() 推断相等与否equal_range() 推断相等与否(传回一个上下限区间范围)fill() 改填元素值fill_n() 改填元素值,n 次find() 搜寻find_if() 在特定条件下搜寻
38、find_end() 搜寻某个子序列的最后一次消失地点find_first_of() 搜寻某些元素的首次消失地点for_each() 对范围内的每一个元素施行某动作generate() 以指定动作的运算结果充填特定范围内的元素generate_n() 以指定动作的运算结果充填 n 个元素内容includes() 涵盖於inner_product() 内积inplace_merge() 合并并取代(覆写)iter_swap() 元素互换lexicographical_compare() 以字典排列方式做比较lower_bound() 下限max() 最大值max_element() 最大值所在位
39、置min() 最小值min_element() 最小值所在位置merge() 合并两个序列mismatch() 找出不吻合点next_permutation() 获得下一个排列组合泛型演算法(Generic Algorithms)与 Function Obje4 ctsnth_element() 重新支配序列中第n个元素的左右两端partial_sort() 局部排序partial_sort_copy() 局部排序并复制到它处partial_sum() 局部总和partition() 切割prev_permutation() 获得前一个排列组合random_shuffle() 随机重排remo
40、ve() 移除某种元素(但不删除)remove_copy() 移除某种元素并将结果复制到另一个 containerremove_if() 有条件地移除某种元素remove_copy_if() 有条件地移除某种元素并将结果复制到另一个 containerreplace() 取代某种元素replace_copy() 取代某种元素,并将结果复制到另一个 containerreplace_if() 有条件地取代replace_copy_if() 有条件地取代,并将结果复制到另一个 containerreverse() 颠倒元素次序reverse_copy() 颠倒元素次序并将结果复制到另一个 cont
41、ainerrotate() 旋转rotate_copy() 旋转,并将结果复制到另一个 containersearch() 搜寻某个子序列search_n() 搜寻连续发生 n 次的子序列set_difference() 差集set_intersection() 交集set_symmetric_difference() 对称差集set_union() 联集sort() 排序stable_partition() 切割并保持元素相对次序stable_sort() 排序并保持等值元素的相对次序swap() 置换(对调)s() 置换(指定范围)transform() 以两个序列为基础,交互作用产生第三
42、个序列unique() 将重复的元素摺叠缩编,使成唯一unique_copy() 将重复的元素摺叠缩编,使成唯一,并复制到他处upper_bound() 上限 四、注意细节:1、auto_ptr 不能用new所生成的array作为初值,由于释放内存时用的是delete,而不是delete2、就搜寻速度而言,hash table通常比二叉树还要快510倍。hash table不是C+标准程序库的一员。3、迭代器使用过程中优先选用前置式递增操作符(+iter)而不是选择后置式递增操作符(iter+)。3、迭代器三个帮助函数:advance(),distance(),iter_swap()。 adv
43、ance()可令迭代器前进 distance()可处理迭代器之间的距离。 iter_swap()可交换两个迭代器所指内容。4、hasp函数 makeheap()、push_heap()、pop_heap()、sort_heap()5、/0在string之中并不具有特别意义,但是在一般C形式的string中却用来标记字符串结束。在string中,字符 /0和其他字符的地位完全相同。string中有三个函数可以将字符串内容转换成字符数组或C形式的string。data() 以字符数组的形式返回字符串内容。但末未追加/0字符,返回类型并非有效的C形式string。c_str() 以C形式返回字符串内
44、容(在末尾端添加/0字符)。copy() 将字符串内容复制到“调用者供应的字符数组”中,不添加/0字符。6、容器中用empty来代替检查size是否为0;当使用new得到指针的容器时,切记在容器销毁前delete那些指针;千万不要把auto_ptr放入容器中。7、尽量使用vector和string来代替动态申请的数组;避开使用vector,vector有两个问题第一,它不是一个真正STL容器,其次,它并不保存bool类型。8、迭代器使用过程中,尽量使用iterator代替const_iterator,reverse_iterator和const_reverse_iterator;使用dista
45、nce和advance把const_iterators转化成iterators。typedef deque IntDeque; / 和以前一样typedef IntDeque:iterator Iter;typedef IntDeque:const_iterator ConstIter;IntDeque d;ConstIter ci;. / 让ci指向dIter i(d.begin(); / 初始化i为d.begin()advance(i, distance(i, ci); / 调整i,指向ci位置9、避开对set和multiset的键值进行修改。10、永久让比较函数对相同元素返回false。
46、11、排序选择:1)如果你需要在vector、string、deque或数组上进行完全排序,你可以使用sort或stable_sort。2)如果你有一个vector、string、deque或数组,你只需要排序前n个元素,应该用partial_sort。3)如果你有一个vector、string、deque或数组,你需要鉴别出第n个元素或你需要鉴别出最前的n个元素,而不用知道它们的挨次,nth_element是你应该注意和调用的。4)如果你需要把标准序列容器的元素或数组分隔为满足和不满足某个标准,你也许就要找partition或stable_partition。5)如果你的数据是在list中,
47、你可以直接使用partition和stable_partition,你可以使用list的sort来代替sort和stable_sort。如果你需要partial_sort或nth_element供应的效果,你就必须间接完成这个任务。12、如果你真的想删除东西的话就在类似remove的算法后接上erase。remove从一个容器中remove元素不会转变容器中元素的个数,erase是真正删除东西。13、提防在指针的容器上使用类似remove的算法,在调用类似remove的算法前手动删除和废弃指针。14、尽量用成员函数代替同名的算法,有些容器拥有和STL算法同名的成员函数。关联容器供应了count
48、、find、lower_bound、upper_bound和equal_range,而list供应了remove、remove_if、unique、sort、merge和reverse。大多数情况下,你应该用成员函数代替算法。这样做有两个理由。首先,成员函数更快。其次,比起算法来,它们与容器结合得更好(尤其是关联容器)。那是由于同名的算法和成员函数通常并不是是一样的。15、容器中使用自定义的结构体时,如果用到拷贝与赋值,结构体需要重载operator=符号;比较容器分成相等与不等,相等时重载operator=符号,不等时重载operator符号。比如set、map、multiset、multi
49、map、priority_queue等容器类要求重载operator符号。16、Map/Multimap,Sets/Multisets都不能用push_back,push_front,由于它是自动排序的。Set内的相同数值的元素只能消失一次,Multisets内可包含多个数值相同的元素。Map内的相同数值的元素只能消失一次,Multimap内可包含多个数值相同的元素。内部由二叉树实现,便于查找。17、string 与 数字之间的转换,转换的方法有很多种,一般使用stringstream来实现转换。比如:#include #include #include using namespace std
50、; int main() int i=0; string temp; stringstream s; /string转换为数字 temp = “1234”; si; coutiendl; /数字转换为string i=256; si; temp = s.str(); couttempend; system(pause); return 0; 18、对于自定义的结构体,放入容器中,最好不要对容器进行内存初始化(不要调用memset,zeromemory函数),否则如果结构体中有指针类型的变量时,就会消失问题。 19、Vector的函数泄漏问题定义了一个struct temp char name2
51、56; int i;Vector vect;当对这个vect执行pushback一些temp的结构体后,执行clear这样是否会内存泄露?可以释放掉temp结构体中的name内存吗?解决方法:不行,clear只是把那些元素全部删除掉,并不是释放内存。再者,你这样的定义容器是不需要释放内存的,如果你这样定义,std:vector *pVec。就需要了。先pVec-clear()再 pVec-swap( (std:vector )(*pVec) )。就能实现内存的释放。 20、stl之map erase方法的正确使用STL的map表里有一个erase方法用来从一个map中删除掉指令的一个节点,不存
52、在任何问题。如果删除多一个节点时,需要使用正确的调用方法。比如下面的方法是有问题:for(ITER iter=mapTest.begin();iter!=mapTest.end();+iter)coutfirst:secondendl;mapTest.erase(iter);这是一种错误的写法,会导致程序行为不行知.究其缘由是map 是关联容器,对于关联容器来说,如果某一个元素已经被删除,那么其对应的迭代器就失效了,不应该再被使用;否则会导致程序无定义的行为。正确的使用方法:1).使用删除之前的迭代器定位下一个元素。STL建议的使用方式for(ITER iter=mapTest.begin();iter!=mapTest.end();)cou
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 护理团队活动高清图
- 护理健康教育培训
- 实施个性化阅读提高课堂教学行为有效性-《鸟的天堂》教学案例分析
- 2026二年级数学下册 表内除法综合应用
- 护理团队伦理与法律问题
- 2026六年级数学下册 圆柱表面积变化
- 心理健康辅导责任制度
- 惩罚制度与责任制度
- 房地产值班责任制度
- 2026三年级数学上册 时间单位的思维训练
- 美发店大众点评运营制度
- (2026春新版)部编版三年级道德与法治下册全册教案
- 湖南湘潭市高职单招职业适应性测试考试真题及答案
- 类器官模型用于药物敏感性筛选的新进展
- 2026年湖南省公务员考试《行测》试题及答案
- 2026年及未来5年市场数据中国游艇设计行业发展前景及投资战略规划研究报告
- 宿舍消防安全
- 【地 理】台湾省的地理环境与经济发展课件-2025-2026学年地理湘教版八年级下册
- 小儿支气管哮喘用药
- 殡仪服务合同范本
- 2026年江西单招装备制造大类高分突破卷含答案
评论
0/150
提交评论