STL 基础学习总结
来源:互联网 发布:北京知果科技 编辑:程序博客网 时间:2024/06/05 11:49
0 什么是STL
STL(Standard Template Library)就是标准模板库。STL是泛型编程的实例,用到的技术就是类模板和函数模板。STL的一个重要特点是数据结构和算法的分离。
1 模板概念
模板就是一种使用无类型的参数来产生一系列函数或类。通过模板可以产生类或函数的集合,使它们操作不同的数据类型,从而避免需要为每一种数据类型产生一个独立的类或函数。
函数模板:独立于类型的函数,可产生函数的特定版本;
类模板:跟类相关的模板,如vector,可产生类对特定类型的版本,如vector<int>。
典型的函数模板:
求两个数的最大值:
template <class T>
T max(T a,T b)
{
return(a>b)?a,b;
}
函数模板只是说明,并不能直接执行,需要进行实例化以后才能执行。
模板优点:
1) 克服了C语言上使用不同函数表达相似功能的坏习惯;
2) 克服了C++使用函数重载的繁琐;
模板缺点: 调试比较困难
1 STL六大组件
1.1 容器
容器是可容纳各种数据类型的数据结构。
标准库中定义了两种标准的容器:
1 顺序容器(Sequence)
顺序容器的每个元素的位置取决于元素被插入时设置的位置,和元素值本身无关。顺序容器包括:vector、list和deque;
向量 vector
后部插入/删除,直接访问
链表 list
双向链表,任意位置插入/删除
双向队列 deque
前/后部插入/删除,直接访问
2 关联容器 (Associative container)
关联容器中元素会根据特定的排序规则对每个元素进行排序,与元素插入的顺序无关。关联式容器有:set、multiset、map和multimap。
map
一对一映射,无重复元素,基于关键字查找
multimap
一对一映射,可有重复元素,基于关键字查找
set
快速查找,无重复元素
multiset
快速查找,可有重复元素
1.2 算法
算法是用来操作容器中数据的模板函数,它抽象了对数据结构的操作行为。要使用STL中定义的算法,应首先引入<algorithm>头文件。例如find()用来搜索一个list中的对象,用sort()来对一个vector中的数据进行排序。
算法可以对容器的内容提供不同方式的操作,包括查找、排序、复制、匹配以及元素重组等。
主要有4种类型的算法:
1) 非变易算法,该类算法不对所作用的容器进行任何修改。
算法比较典型的是find()、count()、for_each等;
2) 变易算法,这类算法的特点是会对它们所作用的容器进行修改。
比较有代表性的算法包括copy()、reverse()等;
3) 排序算法,这类算法的特点是对容器进行不同方式的排序,
这类算法比较典型的是sort()、upper_bound()等;
4) 数值算法,它们主要对容器的内容进行数值计算,
这一类算法主要包括accumulate()、adjacent_difference()等。
1.3 迭代器
STL实现要点是将容器和算法分开,使两者彼此独立。迭代器使两个联系起来,迭代器提供访问容器中的方法。
访问容器中的元素:
容器::iterator iter;
for(iter= 容器.begin();iter!=容器.end();iter++)
{
cout<<*iter 或者 iter->first
}
迭代器可分为五种类型
1. 输入迭代器(Input Iterator)——提供对数据的只读访问;
只能一次一个向前读取元素,按此顺序一个个传回元素值。Input迭代器只能读取元素一次,如果你复制Input迭代器,并使原Input迭代器与新产生的副本都向前读取,可能会遍历到不同的值。下表列出了Input迭代器的各种操作行为。
表达式
功能表述
*iter
读取实际元素
iter->member
读取实际元素的成员
++iter
向前步进(传回新位置)
iter++
向前步进(传回旧位置)
iter1 == iter2
判断两个迭代器是否相同
iter1 != iter2
判断两个迭代器是否不相等
2. 输出迭代器(Output Iterator)——提供对数据的只写访问;
Output迭代器和Input迭代器相反,其作用是将元素值一个个写入。operator*只有在赋值语句的左手边才有效。无法检验Output迭代器是否有效,或“写入动作”是否成功。你唯一可以做的就是写入、写入、再写入。下表列出了Output迭代器的有效操作。
表达式
功能表述
*iter = value
将元素写入到迭代器所指位置
++iter
向前步进(传回新位置)
iter++
向前步进(传回旧位置)
3. 前推迭代器(Forward Iterator)——提供对数据的读写操作,并能向前推进的迭代器;
Forward迭代器是Input迭代器与Output迭代器的结合,具有Input迭代器的全部功能和Output迭代器的大部分功能。Forward迭代器能多次指向同一群集中的同一元素,并能多次处理同一元素。下表总结了Forward迭代器的所有操作。
表达式
功能表述
*iter
存取实际元素
iter->member
存取实际元素的成员
++iter
向前步进(传回新位置)
iter++
向前步进(传回旧位置)
iter1 == iter2
判断两个迭代器是否相同
iter1 != iter2
判断两个迭代器是否不相等
iter1 == iter2
复制
4. 双向迭代器(Bidirectional Iterator)——提供对数据的读写操作,并能向前和向后操作;
双向迭代器在Forward迭代器的基础上增加了回头遍历的能力。它支持递减操作符,用以一步一步的后退操作。
5. 随机访问迭代器(Random Access Iterator)——提供对数据的读写操作,并能在数据中随机移动。
Random Access迭代器在Bidirectional迭代器的基础上再增加随机存取能力。因此它必须提供迭代器算数运算。以下对象支持Random Access迭代器:
可随机存取的容器(vector, deque)
strings(字符串,string,wstring)
一般array(指针)
1.4 适配器
适配器是用来修改其他组件接口,与设计模式中的适配器模的达到的效果是一样的。STL中定义了3种形式的适配器:容器适配器、迭代器适配器和函数适配器。
容器适配器——包括栈(stack)、队列(queue)和优先队列(priority_queue),容器适配器是对基本容器类型进行进一步的封装,从而转换为新的接口类型。
迭代器适配器——对STL中基本迭代器的功能进行扩展,该类适配器包括反向迭代器、插入迭代器和流迭代器。
函数适配器——通过转换或修改来扩展其他函数对象的功能。该类适配器有否定器、绑定器和函数指针适配器。函数对象适配器的作用就是使函数转化为函数对象,或将多参数的函数对象转换为少参数的函数对象。
1.5 空间配置器
当容器中保存的是用户自定义类型数据时,有的数据类型结构简单,占用的空间很小,而有的数据类型结构复杂,占用的内存空间较大;并且有的应用程序需要频繁地进行数据的插入删除操作,这样就需要对内存空间进行频繁地申请和释放工作,然而对内存的频繁操作,会产生严重的性能问题。
为了解决这个问题,STL中提供了两个空间配置器:
一个是简单空间配置器,仅仅对C运行库中malloc和free进行了简单的封
装操作;
另一个是基于内存池的控件配置器,即容器在每次申请内存的时候,内存池会基于一定的策略,向操作系统申请较大的内存空间,从而避免每次都向OS申请内存。
STL中的空间配置器就是负责内存的分配和释放的工作。
1.6 函数对象
函数对象,又称为仿函数,STL中的函数对象就是重载了运算符()的模板类的对象,因为该类对象的调用方式类似于函数的调用方式,所以称为函数对象。
2 四种类型转换操作符
1. static_cast:将一个值以符合逻辑的方式转换。
应用到类的指针上,意思是说它允许子类类型的指针转换为父类类型的指针,同时,也能够执行相反动作:转换父类为它的子类。
例如:float x;
Count<<static_cast<int>(x);//把x作为整型值输出
2. dynamic_cast:将多态类型向下转换为其实际静态类型。
只用于对象的指针和引用。当用于多态类型时,它允许任意的隐式类型转换以及相反过程。dynamic_cast会检查操作是否有效。也就是说,它会检查转换是否会返回一个被请求的有效的完整对象。检测在运行时进行。如果被转换的指针不是一个被请求的有效完整的对象指针,返回值为NULL。
例如:
class Car;
class Cabriolet:public Car
{
…
};
void f(Car *cp)
{
Cabriolet *p = dynamic_cast< Cabriolet > cp;
}
3. reinterpret_cast:转换一个指针为其它类型的指针。
它也允许从一个指针转换为整数类型。反之亦然。这个操作符能够在非相关的类型之间转换。操作结果只是简单的从一个指针到别的指针的值的二进制拷贝。在类型之间指向的内容不做任何类型的检查和转换。
例如:
class A {};
class B {};
A *a = new A;
B *b = reinterpret_cast<B *>(a);
4. const_cast一般用于强制消除对象的常量性。
例如:
class C {};
const C *a = new C;
C *b = const_cast<C *>(a);
- STL 基础学习总结
- [STL基础]STL概述+总结
- STL基础学习之vector、stack、deque、list总结
- STL基础学习笔记
- STL学习阶段总结
- stl容器学习总结
- STL容器学习总结
- STL容器学习总结
- STL容器学习总结
- STL容器学习总结
- STL容器学习总结
- stl容器学习总结
- C++ STL 学习总结
- STL容器学习总结
- stl容器学习总结
- STL容器学习总结
- C++ STL 学习总结
- stl容器学习总结
- Linux进程间通信——使用共享内存
- chromium源码如何启用USE_ASH预定义宏
- 搭建一个支持HTTPS的私有DOCKER Registry
- JavaScript设置按下enter键后执行函数
- 微服务实战:深入微服务架构的进程间通信
- STL 基础学习总结
- Maven Intellij 配置下载镜像
- shell-四(数组和函数)
- Docker命令解读-二
- Android优化(三)_延迟电池续航时间
- 编程总结(四)C++中的前置声明
- jsp 前端防止 xss 注入攻击
- Java并发编程:Synchronized及其实现原理
- vue2.0总结 --- vue使用过程中的常见问题