C++ 有一个很重要的库叫做标准库(standard library)。 STL(标准模板库)有事标准库的核心组成部分之一。 我们将会主要谈论到STL.
Q: STL中迭代器(iterators )的重要作用?
迭代器的作用是访问容器中的元素。 假如没有迭代器, 那么N个算法, M个容器类, 由于算法是作用在容器类上的, 所有共有N x M 个实现(implementations)(因为不同的容器有不同的接口), 这就会导致我们的STL的大小是很大的(Not scalable)。
但是由于迭代器的存在, 我们的迭代器为容器类(可以想象成为数据结构)提供统一的接口, 这样对于每一个算法, 就可以通过对应的迭代器(可以访问容器中的每一个元素), 作用到对应的容器上了。 NOTE: 迭代器是容器类的成员变量。 所以, 我们的实现的形式就会有N x M 下降为 N+ M种。 注意迭代器只是为算法提供一种访问容器内元素的统一的接口。 所以算法本身是不知道(看不见)它作用在那个容器上的。 这样STL利用迭代器将算法和容器(理解为数据结构)独立开来。算法只是作用在迭代器上, 而非容器上了。
这种implementations 个数的下降的另一个好处就是easily extensible(容易扩展)。 设想一下, 我们想要编写一个新算法, 当然这个新的算法只需要作用到iterators 上就可以了。 那么all the existing containers can use that new algorithm。 类似的, 当我们定义了一个新的容器, 我们只要提供合适的iterators interface, 那么接下来all the existing algorithms can operate on the new containers。
从上图中, 我们给出如下解释:
1. using namespace std;
STL库的所有内容的命名空间位于std中, 所以只要我们使用STL, 都应该在程序中包含这一句话。
2. vector<int> vec;
这一句话的作用是创建一个 vector of int。 向量就是一个动态数组(can grow and shrink)。 是一个动态分配的内存, 在heap中根、分配。 向量的size
不是固定的。
3. vec.push_back(4)等。
向量具有一个成员函数push_back, 这个函数的作用是appends an element to the end of the array.
4. vector<int>::iterator itr1 = vec.begin(); 等
每一个容器都提供了一个iterator interface, 所以向量就有一个成员函数begin, 和一个成员函数end, begin 返回的是指向向量的第一个元素的迭代器。
end函数返回的是指向向量最后一个元素的后面(注意不是指向最后一个元素)的迭代器。 不难看出iterator是定义在vector类里的类型(scope resolution)
5. *itr
重载了*符号, 返回的是itr 指向的元素。
6.sort(itr1, itr2), 排序算法。
对[itr1, itr2)之间的元素排序。
迭代器表现上看, 类似与指针, 可以自增, 可以解参考,两个迭代器之间可以比较, 赋值等等。 尽管事实上iterator是一个类。
尽管许多程序员很少使用STL, 他们更倾向与自己别写所有的东西。 然而事实上, 我们编写的所有的程序都可以使用C++的标准库(含STL)。 但是我们有很多理由去使用C++的标准库: