首发于你好,C++

你好,C++(40)“有本事的把名字给我留下!”——第8章 用STL优雅你的程序

第8章 用STL优雅你的程序

在见识了C++世界的奇人异事之后,小陈自然是功力倍增、信心满满,遇到什么事都想用C++语言来解决,以期在众人面前显摆自己的功力是如何如何高深。正好,那天老板又对前面的工资程序提出了一个新需求:统计员工中拿高工资的人数,也就是工资高于1000元的员工人数。看到这个新需求,小陈心中暗暗发笑:这还不简单,小菜一碟啊!很快,他为前面的SalarySys类添加上一个GetMaxCount()函数就满足了老板的新需求:

 // 可以统计高工资员工数的SalarySys类
class SalarySys
{
// …
public:
	// 统计工资大于1000的员工人数
	int GetMaxCount()
	{
		int nTotal = 0;  // 总数
		// 循环访问数组中的所有员工对象
		for(int i = 0; i < m_nCount; ++i)
		{
			// 判断工资是否大于1000
			if(m_arrEmp[i]->GetSalary() > 1000)
			{
				++nTotal; 
			}
		}
		
		return nTotal;
	}
// …
};

我们暗自得意、想要把程序拿到老板面前去邀功请赏时,这时过来一位白衣飘飘的“绅士”,对代码看了两眼,嘴里说出一句话来:

“粗鲁!头脑简单四肢发达的程序员才这么干!”

“你说什么?你,你把话给我说清楚。”

自己非常满意的代码居然被人说成是“粗鲁”的代码,小陈心中自然是不服了,转头想找“他”理论理论,没想到“他”已经飘然走远了。为了以后好找“他”算账,于是赶紧问:

“有本事的把名字给我留下!”

“我的中文名字是标准模板库,英文名字是Standard Template Library,不过大家更喜欢叫我STL。”

听到这里,小陈心中一惊:原来“他”就是传说中的优雅绅士STL啊,今日得见,果然名不虚传、气度非凡啊。心中害怕错过这个结识的机会,于是连忙说道:

“STL先生,别走啊,我们交个朋友吧!”

8.1 跟STL做朋友

要想跟STL做朋友,自然得先从了解STL开始。

8.1.1 算法 + 容器 + 迭代器 = STL

STL,即标准模板库,是一个具有工业强度的、高效的C++函数库。据C++世界的“老人们”说,STL最初诞生于惠普实验室,它是由Alexander Stepanov、Meng Lee和David R. Musser在惠普实验室工作时所开发出来的,后来经过不断地发展形成不同的版本并得到广泛的应用。现在,它已经被纳入C++标准函数库(C++ Standard Library),是ANSI/ISO C++标准中最新的也是极具创新性的一部分。

从广义上讲,STL主要分成三大核心部分:算法(algorithm)、容器(container)和迭代器(iterator)。除此之外还有容器适配器(container adaptor)、函数对象(functor)等。几乎STL的所有代码都采用了模板类和模板函数的方式,这相比于传统的由函数和类组成的库来说提供了更好的代码重用机会。下面先对STL的三大核心部分做一个简单了解。

1. 容器

在程序中,我们总是使用各种数据结构(比如链表、队列等)来组织数据并对其进行管理。常用的数据结构数量有限,并且每个人实现的相同数据结构的代码都十分相似,仅仅是为了适应不同的数据类型变化而在细节上有所出入而已。正是因为这一点,STL容器允许重复利用已有的实现,它提供了一些基础数据结构的模板类,比如list<T>、queue<T>等,我们通过设置特定数据类型为模板参数T,就可以构造出自己的特定类型下的数据结构。通过这种方式,我们将那些重复而乏味的基础数据结构的构造工作简化,从而大大提高了开发效率。

2. 算法

算法是应用在容器上的以各种方法处理容器中数据的行为。跟数据结构一样,程序中的算法同样也有很大的通用性,你开发的稳定性排序算法跟我开发的稳定性排序算法在本质上是一样的,最多只是在操作不同数据类型的数据上有所差异。相同的轮子,没必要重复发明两次。STL将编程时常见的一些通用算法收集起来,同时通过迭代器跟容器配合使用,使它可以适应不同的数据结构和数据类型。当我们需要使用这些通用算法时,直接使用STL提供的版本就行了,比如直接使用STL中的stable_sort()函数配合容器就可以完成数据的稳定性排序,无需我们自己再去实现一次。这样就做到了很好的代码复用,提高了开发效率。

3. 迭代器

图8-1 STL的三大核心部分

如果容器用于容纳数据、算法用于处理数据,那么迭代器就像胶水一样将算法和容器紧密地结合在一起。迭代器提供了一种统一的接口供算法访问各种容器中的数据。这就使得算法的实现与容器的具体类型无关。如果没有迭代器,处理数据的算法就很可能和容纳数据的容器相互分离了,为了处理容器中的数据,我们不得不指针特定的容器实现特定的算法,这样会让数据和算法藕合在一起,为某种容器实现的算法无法操作另一种容器,算法丧失了它的通用型知。

STL中的这三大组成部分,容器负责容纳数据,算法负责处理数据,而迭代器正好将两者联系在一起。正是算法、容器和迭代器这三个核心部分相互配合、相互作用,使得STL成为了一个有机的整体,如图8-1所示。

发布于 2017-01-02 19:10