【STL】初识STL

1.STL是什么

​ 标准模板库(Standard Template Library,简称STL)简单说,就是一些常用数据结构和算法的模板的集合。

​ 广义上讲,STL分为3类:Algorithm(算法)、Container(容器)和Iterator(迭代器),容器和算法通过迭代器可以进行无缝地连接。

​ 详细的说,STL由6部分组成:容器(Container)、算法(Algorithm)、 迭代器(Iterator)、仿函数(Function object)、适配器(Adaptor)、空间配制器(Allocator)。

简单总结一下 :学习 STL 的三个境界: 能用,明理,能扩展
STL的缺陷:
1. STL 库的更新太慢了。这个得严重吐槽,上一版靠谱是 C++98 ,中间的 C++03 基本一些修订。 C++11出 来已经相隔了 13 年, STL 才进一步更新。
2. STL 现在都没有支持线程安全。并发环境下需要我们自己加锁。且锁的粒度是比较大的。
3. STL 极度的追求效率,导致内部比较复杂。比如类型萃取,迭代器萃取。
4. STL 的使用会有代码膨胀的问题,比如使用 vector/vector/vector 这样会生成多份代码,当然这是模板语法本身导致的。

2.STL六大组件

  1. 容器(Container)

    ​ 是一种数据结构, 如list, vector, 和deques,以模板类的方法提供。为了访问容器中的数据,可以使用由容器类输出的迭代器。

  2. 算法(Algorithm)

    ​ 是用来操作容器中的数据的模板函数。例如,STL用sort()来对一 个vector中的数据进行排序,用find()来搜索一个list中的对象, 函数本身与他们操作的数据的结构和类型无关,因此他们可以用于从简单数组到高度复杂容器的任何数据结构上。

  3. 迭代器(Iterator)

    ​ 提供了访问容器中对象的方法。例如,可以使用一对迭代器指定list或vector中的一定范围的对象。 迭代器就如同一个指针。事实上,C++ 的指针也是一种迭代器。 但是,迭代器也可以是那些定义了operator*()以及其他类似于指针的操作符方法的类对象;

  4. 仿函数(Function object)

    ​ 仿函数又称之为函数对象, 其实就是重载了操作符的struct,没有什么特别的地方。

  5. 适配器(Adaptor)

    ​ 简单的说就是一种接口类,专门用来修改现有类的接口,提供一中新的接口;或调用现有的函数来实现所需要的功能。主要包括3中适配器Container Adaptor、Iterator Adaptor、Function Adaptor。

3.STL中的容器、算法和迭代器

容器:置物之所也

​ 容器可以用于存放各种类型的数据(基本类型的变量,对象等)的数据结构,都是模板类,分为顺序容器、关联式容器、容器适配器三种类型,三种类型容器特性分别如下:

序列式容器:强调值的排序,序列式容器中的每个元素均有固定的位置。例如:vector,deque,list等。

关联式容器:二叉树结构,各元素之间没有严格的物理上的顺序关系。例如:set/multiset,map/multimap

容器适配器:封装了一些基本的容器,使之具备了新的函数功能,比如把deque封装一下变为一个具有stack功能的数据结构。这新得到的数据结构就叫适配器。包含stack,queue,priority_queue。

算法:问题之解法也

有限的步骤,解决逻辑或数学上的问题,这一门学科我们叫做算法(Algorithms),算法分为:质变算法非质变算法

质变算法:是指运算过程中会更改区间内的元素的内容。例如拷贝,替换,删除等等。

非质变算法:是指运算过程中不会更改区间内的元素内容,例如查找、计数、遍历、寻找极值等等。

迭代器:容器和算法之间的粘合剂

​ ​ Iterator(迭代器)模式又称游标(Cursor)模式,用于提供一种方法顺序访问一个聚合对象中各个元素, 而又不需暴露该对象的内部表示。 或者这样说可能更容易理解:Iterator模式是运用于聚合对象的一种模式,通过运用该模式,使得我们可以在不知道对象内部表示的情况下,按照一定顺序(由iterator提供的方法)访问聚合对象中的各个元素。 由于Iterator模式的以上特性:与聚合对象耦合,在一定程度上限制了它的广泛运用,一般仅用于底层聚合支持类,如STL的list、vector、stack等容器类及ostream_iterator等扩展Iterator。

迭代器种类:

种类功能支持运算
输入迭代器对数据的只读访问只读,支持++、==、!=
输出迭代器对数据的只写访问只写,支持++
前向迭代器读写操作,并能向前推进迭代器读写,支持++、==、!=
双向迭代器读写操作,并能向前和向后操作读写,支持++、--,
随机访问迭代器读写操作,可以以跳跃的方式访问任意数据,功能最强的迭代器读写,支持++、--、[n]、-n、<、<=、>、>=

常用的容器中迭代器种类为双向迭代器,和随机访问迭代器。

4.容器算法迭代器初识

vector存放内置数据类型

容器:vector                        算法:for_each                迭代器:vector<int>::iterator

代码示例:

#include <vector>
#include <algorithm>
#include <iostream>

using namespace std;

void MyCout(int val)
{
    cout << val << endl;
}

void test1()
{
    // 创建vector容器
    vector<int> v;
    v.push_back(5);
    v.push_back(8);
    v.push_back(11);
    v.push_back(9);
    v.push_back(6);
    vector<int>::iterator vbegin = v.begin();
    vector<int>::iterator vend = v.end();
    // 第一种遍历方式
    for (vector<int>::iterator i = v.begin(); i != v.end(); i++)
    {
        MyCout;
    }
    // 第二种遍历方式
    for_each(v.begin(), v.end(), MyCout);
}

int main()
{
    test1();
    return 0;
}

注意:迭代器实际上是指向容器元素的对象,而不是直接的元素值。当你使用 MyCout(i) 时,i 是一个迭代器,而 MyCout 需要的是一个 int 类型的值。通过 *i 可以解引用迭代器,得到它指向的元素值,这样才能正确传递给 MyCout 函数。所以MyCout()函数中可以不需要传递参数。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值