对于STL我真的是久仰大名了,这次从《Cpp Primer Plus》中初次学习STL中的一些知识,学习到迭代器将算法从具体的容器类型中抽离出来,真的是很nb的想法。
我在这里稍微总结下我初次学习STL时候对其中迭代器和函数符概念的一点理解。

泛型编程

首先还是泛型编程,这种编程的范式是我之前没有接触过的,之前的面向对象编程的关注点是编程的数据方面,例如如何控制数据的访问权限等等。但是泛型编程的关注点是算法,例如将算法从数据类型中抽离出来,将算法从容器类型中抽离出来等等。
虽然面向对象和泛型编程的思想都是抽象和创建可重用的代码,但他们的理念是决然不同的。

C++中的模板为编写独立于数据类型的函数和类提供了可能,而STL通过迭代器将编写独立于容器类型的通用函数提供了可能。


STL中的迭代器

这里的迭代器当然和python中的迭代器不同啦,python中的迭代器可以理解为为实现for...in...语法糖而实现了__iter__()next()迭代协议的类。而STL中的迭代器虽然也是类,但是理念完全不同。
理解迭代器是理解STL的关键所在。
迭代器的存在使得泛型编程能够使用同一个函数如find()来处理不同的容器类型(数组、链表和其他任何容器),及函数不仅独立于容器中存储的数据类型,而且还独立于容器本身的数据结构(算是将泛类型的抽象更提高了一层!)。
模板提供了存储在容器中的数据类型的通用表示,因此还需要遍历容器中的之的通用表示,迭代器正是这样的通用表示。

迭代器是一种广义的指针,其作用和指针类似,这样也就为访问容器中的内容提供了可能
迭代器类应该具有以下几个特征:

  • 能够对迭代器对象执行接触引用的操作–重载*运算符
  • 能够进行赋值
  • 能够进行比较–重载==,>, <等运算符
  • 能够遍历容器中的元素–重载++运算符

例如链表迭代器中重载++运算符函数定义可以是:

1
2
3
4
5
iterator & operator++()
{
pt = pt->next;
return *this;
}

另外每个容器类中都有个typedef的iterator类型,通过作用域解析运算符可以访问该类型来定义迭代器类型的变量:

1
vector<double>::iterator pr;

同时也可以使用C++11中auto关键字来达到目的:
1
2
vector<double> test(10, 0.1);
auto pr = test.begin();


STL中的函数符

函数符可以看成是广义的函数,但他其实是重载了()运算符的一个类,这是理解函数符的关键。
例如一个类:

1
2
3
4
5
6
7
8
class Functor
{
private:
double a;
public:
Functor(double a_ = 1.0) : a(a_) {}
double operator(double x) { return a*x; }
}

这样就能够将Functor类的对象当作函数来用,例如
1
2
Functo f1(2.0);
double y = f1(9.0); // y = 18.0


这里就写这么点吧,以后在使用的时候有新的理解我会在写总结的。
另外附上一个可以方便查询的网站,我一般有些函数的原型忘记了会到这里来查:http://www.cplusplus.com/

Comments

2016-03-16