跳转至

1 STL六大部件

程序=算法+数据,所以STL中包含了容器与算法,容器即存储数据的东西。

【容器】容器用来放东西,东西要占用内存。容器会帮我们解决内存的事情,你不需要管内存,只要把东西一个一个放进去、或者取出来

【分配器】我们使用容器不需要管理内存,所以容器的背后要有另外一个部件支持,就是分配器。分配器用来支持容器做内存管理

【算法】把数据放到容器之后,用户要对容器进行操作,有一些操作在容器本身就可以做,但是还有更多的东西被独立出来,放到模板函数中,这就是“算法”部件。

【说明】OOP和GP的区别

  • 面向对象的思想鼓励我们把数据放在类里头,把处理类的函数放在类里头,形成一个类
  • 但在STL中,数据在“容器”里面,操作这些数据的动作在“算法”里面,容器和算法是剥离开的
  • 所以,两者的设计思想是不一样的,后者是模板编程思想

【迭代器】算法要处理容器的数据。算法是操作,容器是数据,算法与容器的桥梁叫迭代器。迭代器就像一个泛化指针

【仿函数】仿函数,仿,它的使用方法很像是一个函数。

【适配器】适配器可以帮我们转换其他部件

示例

int ia[6] = {27, 210, 12, 47, 109, 83};
vector<int, allocator<int>> vi(ia, ia+6);   //容器

count_if(   //算法:计算满足条件的个数
    vi.begin(), vi.end(),   //迭代器,计算的范围
    //条件:所谓条件,在STL中有一个名称叫predicate,即判断为true的意思
    not1(   //条件取反,是一个适配器
        bind2nd(    //绑定第二参数
            less<int>(),    //仿函数,比较a、b
            40
        )
    )
);

count_if数数,计算满足条件的元素个数

条件:大于等于40

  1. 标准库有一个仿函数less<int>(),表示比较a、b,如果a<b,则返回true
  2. 但现在条件是小于40,而不是比较a、b,所以less不太适合
  3. 可以使用STL的另一个部件“适配器”bind2nd,绑定第二参数
  4. bind2nd(less<int>(), 40); 将40绑定给less做第二参数b,原先是比较a、b大小,现在变成比较a和40的大小。如果a<40,则返回true
  5. not1又是一个适配器,做了取反的动作。原先的意思是小于40返回true,而取反就是大于等于40返回true

所谓“条件”,在STL中有一个名称叫predicate,即判断为true的意思。

复杂度Big-oh

谈到算法、谈到容器,免不了的会想,用哪个比较好,哪个效率比较高。如果这个有答案,那就奇怪了,如果有答案,他直接给你提供一个最好的就够了,何必提供这么多个。用哪个取决于数据的分布与使用的状况

复杂度:

“前闭后开”区间

标准库规定,标识前和尾是这样标识的

  1. begin:指向第一个元素
  2. end:指向最后一个元素的下一个位置

说明:其实怎么标识都没有优劣之分,不过都要用一个标准,STL使用前闭后开的方式

range-based for statement(since C++11)

在C++2.0之后,有一个更方便的写法

auto关键字

可以使用auto关键字自行推导。