学习并使用C++容器已经很长时间了,但一直对容器(container),迭代器(iterator),算法(algorithm)之间的关联及原理不是十分的清楚,最近闲来无事,翻出了候老师的几篇文章仔细阅读了一边,虽然依然对其中的概念不是彻底地了解,但较之自己之前还是有了新的认识。
STL背后的主要思想是C++ Template和泛型编程,为了弄清楚container,iterator,algorithm三者之间的关系,我们首先应该对Template及泛行编程的概念作一下简单的了解:
Template机制的主要作用是将程序中用到的类型信息进行参数化,这样带来的好处就是对于同一个程序接口,其操作对象就不仅仅限于一个特定的数据类型,大大增加了程序接口的普适性。此时你也会有疑问,不同的数据类型有自己的特性格式,怎么可能通过一个接口对这些形式和特性各异的数据烈性进行同一的操作呢?的确,要对形式各异的数据类型进行统一的操作是一件很困难的事情,为了让的接口可以对这些形式各异的数据类型进行统一的操作,需要对这些形式各异的数据类型进行一些抽象(强制的规定,使其满足一定的条件),然后在接口中对数据进行处理的时候,我们操作只针对这些抽象的接口进行编程,这就是Template机制要实现的主要功能。
Template机制包含两个方面的内容:类型模板和函数模板,现在我们先从函数模板着手,逐渐去体会Template机制的奥妙,下面是一个比较两个数据大小的函数模板:
template <typename T> bool is_bigger( const T&t1, const T &t2 ) {
return t1 > t2;//从这里我们可以看出,如果数据类型想通过给函数模板进行大小的判断,改数据类型必须支持比较操作符
}
struct Unit {
friend bool operator>(const Unit &u1, const Unit &u2 );
Unit( double p ) : price(p){}
double price;
}
bool operator>(const Unit &u1, const Unit &u2){
return u1.price > u2.price;
}
is_bigger<int>( 1, 3);
Unit u1(1), u2(3);
is_bigger<Unit>(u1,u2);
在上面的函数模板中,数据类型被参数话了,任何数据类型只要支持比较符 ">",就可以利用改接口进行操作
,这样就减少了需要维护的代码的数量,同时也增加了系统的可维护性,比如我们新加了一个数据类型City,想要通过改接口来实现两个城市面积的比较的话,只要对City提供一个">"操作符操作即可。
到这里,已经了解了函数模板的主要概念,下面开始说一下类模板。模板机制的核心概念是通过数据类型的参数话来实现对满足特定条件的一组类型实现统一的操作,而类的核心思想是对数据和围绕数据的操作进行封装,那么我们就可以将具有相似操作的数据类进行模板化,使其可以对所有类似的数据进行操作,至此类模板的出现已经水到渠成,下面就通过一个例子还了解一下类模板的概念。
看到这里你也许说我确确实实体会到了Template机制的好处,但是这些好像与container,iterator,algorithm的关系不大。的确,如果仅仅是这些还不能体现出Template机制在泛型编程中的重要作用,但这些基本的概念将会对你下一步的理解至关重要。