跟我学STL系列(1)——STL入门介绍
一、引言
最近这段时间一直都在自学C++,所以这里总结下自己这段时间的学习过程,通过这种方式来巩固自己学到的内容和以备后面复习所用,另外,希望这系列文章可以帮助到其他自学C++的朋友们。
由于本人之前主要研究C#语言,在自学C++的过程中,经常会把C++中内容与C#中内容进行对比来理解,所以这系列文章的内容也会与C#进行比较,从而来说明语言都是想通的,只要你掌握好一门语言,学习其他语言都可以举一反三。
二、STL是什么
STL全称为Standard Template Library,即标准模板库,该库提供一些常用的容器对象和一些通用的算法等,大家可以理解STL就是一个库,该库帮我们封装了很多容器类和通用的方法,我们可以通过调用该库中封装好的方法和容器类来进行编程,相比C#而言,STL就好比.NET类库中的某个DLL,例如,C# 中,List<T>类存在于mscorlib.dll中System.Collections.Generic命名空间下,C++ 中,list<T>存在于list头文件中std命名空间下,所以C++代码中要使用list<T>容器(在C++中把list成为容器,即一系列元素的集合),必须先通过#include <list>引入list头文件,类似与C#中的添加mscorlib.dll引言,再使用use namespace std引入命名空间,类似与C#中using System.Collections.Generic代码。
三、STL 六大组件
STL通过模板抽象了基于数据结构之上的普遍行为,形成了独特的STL算法。在STL中,这些数据结构成为容器。在容器和算法之间通过中间体:迭代器来进行连接,迭代器可以看做是数据结构和算法之间的纽带,它降低了数据结构和算法之间的耦合度。STL中国又包括六大核心组件,它们分别是:
- 容器(Container)
- 算法(Algorithm)
- 迭代器(Iterator)
- 函数对象,又称仿函数(Function object)
- 适配器(Adaptor)
- 空间配置器(Allocator)
3.1 容器
STL中容器可分为序列式容器和关联式容器,其中,序列式容器的每个元素的位置取决于元素被插入时设置的位置,和元素值本身无关,而,关联式容器的元素位置取决于特定的排序规则,和插入顺序无关。意思就说,序列式容器中每个元素的位置与插入的顺序对应,而关联式容器中元素会根据特定的排序规则对每个元素进行排序,与元素插入的顺序无关,更多内容可以参考本系列后面文章介绍。
容器 | 特征 | 内存结构 | 可随机存取 | 元素搜寻速度 | 头文件 |
vector | 在序列尾部进行插入和删除,访问和修改元素的时间复杂度为O(1), 但插入和删除的时间复杂度与到末尾的距离成正比。 |
单端数组 | 可以 | 慢 | <vector> |
list | 对任意元素的访问与两端的距离成正比,但对某个位置的插入和删除 花费为常数时间,即O(1) |
双向链表 | 否 | 非常慢 | <list> |
deque | 与vector基本相同,唯一不同的是,在序列头部插入和删除的 时间复杂度也是O(1) |
双端数组 | 可以 | 慢 | <deque> |
set | 由节点组成的红黑树,具有快速查找的功能 | 二叉树 | 否 | 快 | <set> |
multiset | 可以支持重复元素,同样具有快速查找能力 | 二叉树 | 否 | 快 | <set> |
map | 由{键,值}对组成的集合,同样具有快速查找能力 | 二叉树 | 对key而言可以 | 对key而言快 | <map> |
multimap | 一个键可以对应于多个值,同样具有快速查找能力 | 二叉树 | 否 | 对key而言快 | <map> |
操作 | Dictionary<Key,Value> | SortedDictionary<Key,Value> |
this[key] | O(1) | O(logn) |
Add(key,value) | O(1) | O(logn) |
Remove(key) | O(1) | O(logn) |
ContainsKey(key) | O(1) | O(logn) |
ContainsValue(value) | O(1) | O(n) |
3.2 算法
3.3 迭代器
STL实现要点是将容器和算法分开,使两者彼此独立。迭代器使两个联系起来,迭代器提供访问容器中的方法。迭代器实质上是一种智能指针,它重载了->和*操作符。事实上,C++指针也是一种迭代器。在C#中同样有迭代器的概念,具体参考MSDN:http://msdn.microsoft.com/zh-cn/library/dscyy5s0(v=vs.90).aspx,不同的是,在C++ 中迭代器分为五类,这五类分别为:
- 输入迭代器(Input Iterator)——提供对数据的只读访问;
- 输出迭代器(Output Iterator)——提供对数据的只写访问;
- 前推迭代器(Forward Iterator)——提供对数据的读写操作,并能向前推进的迭代器;
- 双向迭代器(Bidirectional Iterator)——提供对数据的读写操作,并能向前和向后操作;
- 随机访问迭代器(Random Access Iterator)——提供对数据的读写操作,并能在数据中随机移动。
3.4 函数对象
函数对象,又称为仿函数,STL中的函数对象就是重载了运算符()的模板类的对象,因为该类对象的调用方式类似与函数的调用方式,所以称为函数对象,函数对象类似于C#中的委托对象,熟悉C#的朋友肯定知道,我们可以隐式地调用委托,即委托对象(实参),更多关于委托内容可以参考我的博文:委托的本质论。
3.5 适配器
适配器是用来修改其他组件接口,与设计模式中的适配器模的达到的效果是一样的。STL中定义了3种形式的适配器:容器适配器、迭代器适配和函数适配器。
容器适配器——包括栈(stack)、队列(queue)和优先队列(priority_queue),容器适配器是对基本容器类型进行进一步的封装,从而转换为新的接口类型。
迭代器适配器——对STL中基本迭代器的功能进行扩展,该类适配器包括反向迭代器、插入迭代器和流迭代器。
函数适配器——通过转换或修改来扩展其他函数对象的功能。该类适配器有否定器、绑定器和函数指针适配器。函数对象适配器的作用就是使函数转化为函数对象,或将多参数的函数对象转换为少参数的函数对象,如STL中bind2nd()就是绑定器。
3.6 空间配置器
当容器中保存的是用户自定义类型数据时,有的数据类型结构简单,占用的空间很小,而有的数据类型结构复杂,占用的内存空间较大;并且有的应用程序需要频繁地进行数据的插入删除操作,这样就需要对内存空间进行频繁地申请和释放工作,然而对内存的频繁操作,会产生严重的性能问题,为了解决这个问题,STL中提供了两个空间配置器,一个是简单空间配置器,仅仅对C运行库中malloc和free进行了简单的封装操作,另一个是“基于内存池的控件配置器”,即容器在每次申请内存的时候,内存池会基于一定的策略,向操作系统申请交大的内存空间,从而避免每次都向OS申请内存。STL中的空间配置器就是负责内存的分配和释放的工作。
四、STL中容器使用示例
看完STL组件之后,现在我们具体看看如何使用STL中的容器进行编程,下面示例是对vector容器进行简单的几个操作。具体代码如下:
#include <iostream>
// 要使用vector容器必须加入vector头文件
#include <vector>
// 引入算法头文件
#include <algorithm>
// 引入std命名空间,如果不引入命名空间,则必须像std::vector这样方式来使用vector容器
using namespace std; void main()
{
// 初始化vector容器对象
vector<int> vec;
for(int i=;i<;i++)
{
// 向vector中添加一个元素
vec.push_back(i);
} // 使用数组初始化vector容器
int a[]={,,,,,};
vector<int> vec2(a,a+); // 使用a数组第一位到第六位来初始化vector容器 // 定义迭代器对象
vector<int>::iterator begin; // 遍历vector集合
for(begin =vec.begin();begin!=vec.end();begin++)
{
// 输出vector容器中的元素
cout<<*begin<<" ";
}
cout<<endl; // 对vec2容器排序
sort(vec2.begin(),vec2.end());
// 遍历vector集合
cout<<"对vec2容器排序后的结果:"<<endl;
for(begin =vec2.begin();begin!=vec2.end();begin++)
{
// 输出排序后vec2容器中的元素
cout<<*begin<<" ";
}
cout<<endl;
}
上面代码的输出结果如下图所示:
五、小结
跟我学STL系列(1)——STL入门介绍的更多相关文章
- 跟我一起学Go系列:gRPC 入门必备
RPC 的定义这里就不再说,看文章的同学都是成熟的开发.gRPC 是 Google 开源的高性能跨语言的 RPC 方案,该框架的作者 Louis Ryan 阐述了设计这款框架的动机,有兴趣的同学可以看 ...
- 红豆带你从零学C#系列—Visual Studio工具介绍、下载和安装
一.Visual Studio的下载 Visual Studio(简称VS)是微软的一套完整的开发工具集,集成了能够开发并运行如C#.C++.VB.F#等程序的开发环境,目前最新的版本是Visual ...
- 跟我一起学 Go 系列:gRPC 拦截器
Go gRPC 学习系列: 跟我一起学Go系列:gRPC 入门必备 第一篇内容我们已经基本了解到 gRPC 如何使用 .对应的三种流模式.现在已经可以让服务端和客户端互相发送消息.本篇仍然讲解功能性的 ...
- 跟我一起学Go系列:Go gRPC 安全认证机制-SSL/TLS认证
Go gRPC 系列: 跟我一起学Go系列:gRPC 拦截器使用 跟我一起学Go系列:gRPC 入门必备 第一篇入门说过 gRPC 底层是基于 HTTP/2 协议的,HTTP 本身不带任何加密传输功能 ...
- 跟我一起学Go系列:Go gRPC 安全认证方式-Token和自定义认证
Go gRPC 系列: 跟我一起学Go系列:gRPC安全认证机制-SSL/TLS认证 跟我一起学 Go 系列:gRPC 拦截器使用 跟我一起学 Go 系列:gRPC 入门必备 接上一篇继续讲 gRPC ...
- [Android开发学iOS系列] Auto Layout
[Android开发学iOS系列] Auto Layout 内容: 介绍什么是Auto Layout. 基本使用方法 在代码中写约束的方法 Auto Layout的原理 尺寸和优先级 Auto Lay ...
- 《STL系列》之map原理及实现
上一篇文章<STL系列>之vector原理及实现,介绍了vector的原理及实现,这篇文章介绍map的原理及实现.STL实现源码下载.STL中map的实现是基于RBTree的,我在实现的时 ...
- [C/C++] C/C++延伸学习系列之STL及Boost库概述
想要彻底搞懂C++是很难的,或许是不太现实的.但是不积硅步,无以至千里,所以抽时间来坚持学习一点,总结一点,多多锻炼几次,相信总有一天我们会变得"了解"C++. 1. C++标准库 ...
- STL笔记(2) STL之父访谈录
年3月,dr.dobb's journal特约记者, 著名技术书籍作家al stevens采访了stl创始人alexander stepanov. 这份访谈纪录是迄今为止对于stl发展历史的最完备介绍 ...
随机推荐
- Bootstrap修改input file默认样式
html部分 <div class="form-group"> <label class="col-sm-3 control-label"&g ...
- Kafka深入理解-2:Kafka的Log存储解析
摘自http://blog.csdn.net/jewes/article/details/42970799 引言 Kafka中的Message是以topic为基本单位组织的,不同的topic之间是相互 ...
- webform内置对象
1.Response和Request地址栏数据拼接 QueryString 优点:简单好用:速度快:不消耗服务器内存. 缺点:只能传字符串:保密性差(调转页面后在地址栏显示):长度有限.响应请求对象 ...
- fastJson java后台转换json格式数据
什么事JSON? JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式. 易于人阅读和编写.同时也易于机器解析和生成. 它基于JavaScript Progra ...
- Nginx配置配置文件nginx.conf的设置
引用自:http://www.ha97.com/5194.html #定义Nginx运行的用户和用户组user www www; #nginx进程数,建议设置为等于CPU总核心数.worker_pro ...
- HDOJ 1512 几乎模板的左偏树
题目大意:有n个猴子.每个猴子有一个力量值,力量值越大表示这个猴子打架越厉害.如果2个猴子不认识,他们就会找他们认识的猴子中力量最大的出来单挑,单挑不论输赢,单挑的2个猴子力量值减半,这2拨猴子就都认 ...
- WCF学习记录
一个demo: http://www.cnblogs.com/iamlilinfeng/p/4083827.html
- Sublime 保存时自动转换tab成空格
笔者最近学习c, c语言的清新代码风格让人眼前一亮,不禁爱上这种写作风格,变量名.等号.常量值之间空格分隔,清爽便于阅读. 于是笔者以此为代码写作规范,查阅自己以前写的java代码,以下用notepa ...
- spring默认启动位置以及contextConfigLocation设置源码解析
这几天在看spring的源码,涉及到spring启动位置的部分,下面就看看spring到底是从哪儿开始加载的.本文使用的是spring3.0M3 首先spring的加载会借助一个监听器ContextL ...
- NDK开发总结
NDK开发差不多结束了, 估计后面也不会再碰了诶, 想着还是写个总结什么的,以后捡起来也方便哈.既然是总结,我这里就不会谈具体的细节,只会记录下我觉得重要的东西, 所以这篇随笔不是为萌新学习新知识准备 ...