1.C++标准库和STL
C++标准库以header files形式呈现:
- C++标准库的header files不带后缀名(.h),例如#include <vector>
- 新式C header files 不带后缀名.h,例如#include<cstdio>
- 旧式C header files (带有后缀名.h)仍然可用,例如#include <stdio.h>
- 新式headers内的组件封装于namespace “std”。 using namespace std;或者以 using std::cout;的形式
- 旧式headers 内的组件不封装于namespace "std"
在标准库中,标准模板库STL(Standard Template Library),占据了标准库70%,80%以上的内容。
C++ 标准库的范围大于STL的范围。STL的核心思想是泛型编程(Generic Programming)。
重要资源:
网站:
书籍:
- The C++ standard Library second edition;
- STL 源码剖析
2.STL 六大组件
STL分为六大组件:
- 容器(container):常用数据结构,大致分为两类,序列容器,如vector,list,deque,关联容器,如set,map。在实现上,是类模板(class template)
- 迭代器(iterator):一套访问容器的接口,行为类似于指针。它为不同算法提供的相对统一的容器访问方式,使得设计算法时无需关注过多关注数据。(“算法”指广义的算法,操作数据的逻辑代码都可认为是算法)
- 算法(algorithm):提供一套常用的算法,如sort,search,copy,erase … 在实现上,可以认为是一种函数模板(function template)。
- 配置器(allocator):为容器提供空间配置和释放,对象构造和析构的服务,也是一个class template。
- 仿函数(functor):作为函数使用的对象,用于泛化算法中的操作。
- 配接器(adapter):将一种容器修饰为功能不同的另一种容器,如以容器vector为基础,在其上实现stack,stack的行为也是一种容器。这就是一种配接器。除此之外,还有迭代器配接器和仿函数配接器。
STL 六大组件的交互关系
-
Container通过Allocator取得数据储存空间 -
Algorithm通过Iterator存取Container内容 -
Functor可以协助Algorithm完成不同的策略变化 -
Adapter可以修饰或套接Functor、Iterator。
#include <vector> #include <algorithm> #include <functional> #include <iostream> using namespace std; int main() { int ia[6] = { 27, 210, 12, 47, 109, 83 }; vector<int, allocator<int>> vi(ia, ia + 6); cout << count_if(vi.begin(), vi.end(), not1(bind2nd(less<int>(), 40))); return 0; }
上述这段代码用到了STL的六大部件:
allocator 是分配器,vector 是容器,count_if 是算法
vi.begin() 是迭代器
not1,bind2nd是适配器
less<int> 是仿函数
- 理解容器的前闭后开的设计。迭代器类似于指针,很多操作和指针差不多++,--运算。vec.begin(),vec.end()指向容器最后一个元素的下一个位置,解引用*(vec.end())错误!
- auto关键字的应用
c++知识点
临时对象
1 //临时对象的产生与运用 2 #include <vector> 3 #include <iostream> 4 #include <algorithm> 5 using namespace std; 6 7 template <typename T> 8 class print 9 { 10 public: 11 void operator()(const T& elem) // operator()重载 12 { 13 cout<<elem<<' '; 14 } 15 }; 16 17 int main() 18 { 19 int ia[6] = {0,1,2,3,4,5}; 20 vector<int> iv(ia, ia+6); 21 22 // print<int>() 是一个临时对象,不是函数调用 23 for_each(iv.begin(), iv.end(), print<int>()); 24 25 cout<<endl; 26 27 return 1; 28 }