目录

重学C++:容器和迭代器


常见的坑

  1. 所有标准库容器都支持迭代器,而只有少数几种支持下标运算符。

  2. string虽然不是容器,但是支持很多容器的操作。

  3. 容器不为空时:begin()返回的是容器中第一个元素的位置;end()返回的是容器中最后一个元素的后一个位置

    容器为空时:begin()end()返回的都是最后一个元素的后一个位置

  4. 任何可能改变容器大小的操作都会使容器的迭代器失效。

必须要理解的点

  1. 和指针类似的是,迭代器支持对对象的间接访问。

  2. 和指针不同的是,获取迭代器不使用取地址符,有迭代器的类型都拥有返回迭代器的成员函数,如begin(), end()

  3. 所有迭代器都支持的运算:

    运算符 例子 含义
    * *iter 返回迭代器iter指向元素的引用
    -> iter->mem 解引用iter并获取该元素名为mem的成员,即(*iter).mem
    ++ ++iter iter指向当前元素的后一个元素
    --iter iter指向当前元素的前一个元素
    == iter1 == iter2 如果两个迭代器指向相同的元素返回true,否则返回false
    != iter1 != iter2 上面例子的反面
  4. 迭代器的类型有两种:iteratorconst_iterator

    1
    2
    3
    4
    5
    
    vector<int>::iterator itv;          // 可用于读写vector<int>中的元素
    string::iterator its;               // 可用于读写string对象中的元素
    
    vector<int>::const_iterator citv;   // 只能读取元素
    string::const_iterator cits;        // 只能读取元素
    

    begin()end()返回哪一种取决于对象本身是否被const修饰。

    C++11中引入了cbegin()cend()来专门返回const_iterator

  5. 认定一种类型是迭代器当且仅当它支持一套操作,这套操作能使我们访问容器内的元素或从某一个元素移动到另一个元素。

  6. vectorstring的迭代器支持的额外的运算:

    运算 含义
    iter + n 运算得到一个新迭代器,指向当前元素的后n个元素的位置
    iter - n 运算得到一个新迭代器,指向当前元素的前n个元素的位置
    iter += n 运算得到的新迭代器赋值给iter
    iter -= n 同上
    iter1 - iter2 两个迭代器之间的距离,可正可负
    >, <, <=, >= 同两类型的下标运算符中的数字的关系,位置靠前的较小

建议

  1. 一般不在意迭代器的类型,因此使用auto来标注。
  2. 循环结束的判断条件习惯使用迭代器和!=,这样可以不用在意容器类型。
  3. 凡是使用了迭代器的循环体中都不能有改变容器大小的操作如push_back()