zoukankan      html  css  js  c++  java
  • C++ Primer : 第九章 : 顺序容器的定义、迭代器以及赋值与swap

    顺序容器属于C++ STL的一部分,也是非常重要的一部分。

    顺序容器包括:

    std::vector,包含在头文件<vector>中

    std::string, 包含在头文件<string>中

    std::deque,包含在头文件<deque>中

    std::list,包含在头文件<list>中

    std::forward_list,包含在头文件<forward_list>中

    std::array, 包含在头文件<array>中


    顺序容器几乎可以保存任意类型的元素,我们可以定义一个容器,其元素类型可以是另一个容器。顺序容器的构造函数的一个版本接受容器大小的参数,它使用了元素类型的默认构造函数,但有些类没有构造函数,我们可以定义一个保存这种类型对象的容器,但我们在构造这种容器时不能只传递给它一个元素数目的参数,必须提供一个元素初始化器。


    迭代器

    迭代器支持的操作有:*iter,iter->mem,++iter,--iter, iter1 == iter2, iter1 != iter2

    另外,forward_list::iterator 不支持递减--操作。

    另外,string、vector、deque、array的迭代器支持这些算数运算符:

    iter + n, iter - n, iter += n, iter -= n, iter1 - iter2, >、>=、<、<=


    迭代器的范围是 [begin, end),首迭代器和尾后迭代器。



    容器的定义和初始化

    C c;   默认构造函数,如果C是一个array,则c中元素按默认方式初始化,否则c为空;

    C c1(c2);  c1位c2的一个拷贝,c1和c2的容器类型必须相同,而且保存的是相同的类型,

    C c1=c2;    如果C是array,它们的大小必须相同;

    C c{a,b,c,...};  c初始化为初始化列表的中元素,列表中的元素必须与c的元素类型相容。

    C c={a,b,c,...};  对于array类型,列表中的元素个数必须等于或小于array的大小,如果小于,array剩余的元素进行值初始化

    C c(b, e);  c初始化为迭代器b到e(不包括e)之间的元素,迭代器所指向的元素必须与c中元素类型相容

    只有顺序容器(不包括array)的构造函数才接受大小参数

    C seq(n);    seq包含了n个元素,这些元素都进行了值初始化,此构造函数时explicit的

    C seq(n,t);  seq包含n个值为 t 的元素


    将一个容器拷贝为另一个容器时,两个容器的类型和保存的类型必须匹配,当array进行拷贝时,它的大小还必须相等;

    不过,当使用迭代器参数来拷贝元素时,就不要求两个容器必须是同一种容器了,只要两者保存的元素类型能相容就行。


    array的定义和初始化:

    定义一个array时,需要制定元素类型和大小。

    列表初始化array时,列表中的元素个数不能超过array大小,如果个数小于array大小,将初始化array靠前的元素,剩下的进行值初始化,如果array保存的类型时类类型,则该类必须有一个默认构造函数,以便值初始化能够进行。



    赋值和swap


    c1 = c2;// 将c1的内容替换为c2中元素的拷贝

    c1 = {a, b, c};// 赋值后, c1的大小为3

    array也可以整体赋值,这正是array与内置数组的不同之处; array在赋值时,赋值符号左右两边的对象必须具有相同的类型。

        array<int, 5> a1 = {1, 2, 3, 4, 5};
        array<int, 5> a2 = {6, 7, 8, 9, 10};
        a1 = a2; // a1中元素将替换为a2中元素的拷贝


        但不能将一个花括号列表赋值数组:

        a2 = {0}; // error


    容器的赋值运算有如下几种:

        c1 = c2;
        c  = {a, b, c};
        swap(c1, c2); 将c1中元素替换为c2中的元素,c1和c2必须具有相同的类型
        c1.swap(c2);  swap通常比从c2向c1拷贝元素快的多。
     
        // assign操作不适用于关联容器和array
        seq.assign(b, e); 	        将seq中元素替换为迭代器b和e所指向的范围之内的元素,但是b和e不能指向seq
        seq.assign(il);     	将seq中元素替换为初始化列表il中的元素</span>
        seq.assign(n, val);         将seq中元素替换为n个值为val的元素</span>


    赋值相关运算会导致指向左边容器内部的迭代器、引用和指针失效。而swap操作将容器内容交换不会导致失效。(array和string的情况除外)


    使用swap

    swap操作的是两个相同类型容器的内容。除array外,交换两个容器内部的操作保证会很快,元素本身并未交换,swap只是交换了两个容器内部的数据结构。

    元素不会被移动,这意味着,string除外,指向容器的迭代器、引用和指针在swap操作后不会失效。但在swap之后,这些元素已经属于不同的容器了。例如有两个容器vec1和vec2,假定iter1在swap前指向vec1[3], 在swap之后它指向vec2[3]。  但是,对一个string调用swap会导致迭代器、引用和指针失效。

    swap两个array会真正的交换他们的元素,所以交换array所需要的时间和array的元素数目成正比。

    新的标准库中,容器既提供成员函数版本的swap,也提供非成员函数版本的swap,我们应该习惯使用非成员版本的swap。


    容器大小操作

    每个容器类型都支持相等运算符 == 和 != ; 除了无需关联容器外,所有容器都支持关系运算符 >、>=、<、<= 。关系运算符左右两边的对象必须是相同类型的容器,且必须保存相同类型的元素。

    实际上,容器进行比较时,使用的是元素的关系运算符完成比较,因此,只有当容器储存的元素类型定义了相应的关系运算符时,我们才可以进行关系比较!



  • 相关阅读:
    PAT Basic 1077 互评成绩计算 (20 分)
    PAT Basic 1055 集体照 (25 分)
    PAT Basic 1059 C语言竞赛 (20 分)
    PAT Basic 1072 开学寄语 (20 分)
    PAT Basic 1049 数列的片段和 (20 分)
    蓝桥杯BASIC-13 数列排序
    蓝桥杯入门——3.序列求和
    蓝桥杯入门——2.圆的面积
    蓝桥杯入门——1.Fibonacci数列
    树的总结(遍历,BST,AVL原型,堆,练习题)
  • 原文地址:https://www.cnblogs.com/averson/p/5096076.html
Copyright © 2011-2022 走看看