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
- 标准库有一个仿函数
less<int>()
,表示比较a、b,如果a<b,则返回true - 但现在条件是小于40,而不是比较a、b,所以
less
不太适合 - 可以使用STL的另一个部件“适配器”
bind2nd
,绑定第二参数 bind2nd(less<int>(), 40);
将40绑定给less做第二参数b,原先是比较a、b大小,现在变成比较a和40的大小。如果a<40,则返回truenot1
又是一个适配器,做了取反的动作。原先的意思是小于40返回true,而取反就是大于等于40返回true
所谓“条件”,在STL中有一个名称叫predicate
,即判断为true的意思。
复杂度Big-oh¶
谈到算法、谈到容器,免不了的会想,用哪个比较好,哪个效率比较高。如果这个有答案,那就奇怪了,如果有答案,他直接给你提供一个最好的就够了,何必提供这么多个。用哪个取决于数据的分布与使用的状况
复杂度:
“前闭后开”区间¶
标准库规定,标识前和尾是这样标识的
- begin:指向第一个元素
- end:指向最后一个元素的下一个位置
说明:其实怎么标识都没有优劣之分,不过都要用一个标准,STL使用前闭后开的方式
range-based for statement(since C++11)¶
在C++2.0之后,有一个更方便的写法
auto关键字¶
可以使用auto关键字自行推导。