序言
C++ 语言的核心优势之一就是便于软件的重用。C++ 中有两个方面体现重用:
一是面向对象的继承和多态机制
二是通过模板的概念实现了对泛型程序设计的支持
C++ 的标准模板库(Standard Template Library,STL)是泛型程序设计最成功应用的实例。STL 是一些常用数据结构(如链表、可变长数组、排序二叉树)和算法(如排序、查找)的模板的集合。
有了 STL,程序员就不必编写大多数常用的数据结构和算法。而 STL 是经过精心设计的,运行效率很高,比水平一般的程序员编写的同类代码速度更快。
有一种说法,C++ 是用来编写大程序的,如果只是编写几十上百行的小程序,用 C 语言就可以,没有必要用 C++。
这个说法是不准确的。可以说,小程序没必要用面向对象的方法,但是用 C++ 还是能够带来很大方便的,因为 C++ 中有 STL。哪怕编写只有十几行的程序,也可能会用到 STL 中提供的数据结构和算法。例如对数组排序,用 STL 中的 sort 算法往往只需要一条语句就能解决,而不用像 C 语言库函数 qsort 那样还要编写比较函数。
容器
容器(container)用于存放数据的类模板。可变长数组、链表、平衡二叉树等数据结构在 STL 中都被实现为容器。
程序员使用容器时,即将容器类模板实例化为容器类时,会指明容器中存放的元素是什么类型的。
容器中可以存放基本类型的变量,也可以存放对象。对象或基本类型的变量被插入容器中时,实际插入的是对象或变量的一个复制品。
STL
中的许多算法(即函数模板),如排序、查找等算法,在执行过程中会对容器中的元素进行比较。这些算法在比较元素是否相等时通常用运算符进行,比较大小通常用
<
运算符进行,因此,被放入容器的对象所属的类最好重载
==
和 <
运算符,以使得两个对象用
==
和 <
进行比较是有定义的。
容器分类两大类
顺序容器
顺序容器有以下三种:可变长动态数组 vector、双端队列 deque、双向链表 list。
它们之所以被称为顺序容器,是因为元素在容器中的位置同元素的值无关,即容器不是排序的。将元素插入容器时,指定在什么位置(尾部、头部或中间某处)插入,元素就会位于什么位置。
关联容器
关联容器有以下四种:set、multiset、map、multimap。关联容器内的元素是排序的。插入元素时,容器会按一定的排序规则将元素放到适当的位置上,因此插入元素时不能指定位置。
默认情况下,关联容器中的元素是从小到大排序(或按关键字从小到大排序)的,而且用
<
运算符比较元素或关键字大小。因为是排好序的,所以关联容器在查找时具有非常好的性能。
除了以上两类容器外,STL 还在两类容器的基础上屏蔽一部分功能,突出或增加另一部分功能,实现了三种容器适配器:栈 stack、队列 queue、优先级队列 priority_queue。
容器都是类模板。它们实例化后就成为容器类。用容器类定义的对象称为容器对象。
例如,vector<int>
是一个容器类的名字,vector<int> a;
就定义了一个容器对象 a,a 代表一个长度可变的数组,数组中的每个元素都是
int 类型的变量;vector<double> b;
定义了另一个容器对象 b,a 和 b 的类型是不同的。本教程后文所说的
"容器",有时候也指 "容器对象"。
任何两个容器对象,只要它们的类型相同,就可以用 <、<=、>、>=、!= 进行词典式的比较运算。假设 a、b 是两个类型相同的容器对象,这些运算符的运算规则如下。
a == b: 若 a 和 b 中的元素个数相同,且对应元素均相等,则
a == b
的值为 true,否则值为 false。元素是否相等使用==
运算符进行判断的。a < b: 规则类似于词典中两个单次比较大小,从头到位依次比较每个元素,如果发生 a 中的元素小于 b 中元素的情况,则
a < b
的值为 true;如果没有发生 b 中的元素小于 a 中的元素的情况,且 a 中的元素个数比 b 少,a < b
的值也为 true;其他情况下值为 false。元素比较大小是通过<
运算符进行的。a != b: 等价于 !(a == b)
a > b: 等价于 b < a
a <= b: 等价于 !(b < a)
a >= b: 等价于 !(a < b)
所有容器都有以下两个成员函数:
int size()
: 返回容器中元素的个数。bool empty()
: 判断容器对象是否为空。
顺序容器和关联容器还有以下成员函数:
begin()
: 返回指向容器中第一个元素的迭代器。end()
: 返回指向容器中最后一个元素后面的位置的迭代器。rbegin()
: 返回指向容器中最后一个元素的反向迭代器。rend()
: 返回指向容器中第一个元素前面的位置的反向迭代器。erase(...)
: 从容器中删除一个或几个元素。该函数参数比较复杂,此处省略。clear()
: 从容器中删除所有元素。
如果一个容器是空的,则 begin()
和 end()
的返回值相等,rbegin()
和 rend()
的返回值也相等。
顺序容器还有以下常用成员函数:
front()
: 返回容器中第一个元素的引用。back()
: 返回容器中最后一个元素的引用。push_back()
: 在容器末尾增加新元素。pop_back()
: 删除容器末尾的元素。insert(...)
: 插入一个或多个元素。该函数参数较复杂,此处省略。