• 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。


    容器大小操作

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

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



  • 相关阅读:
    CentOS8安装Mysql5.7
    CentOS8搭建FTP服务器
    CentOS8安装jdk1.8
    基于可穿戴设备的医疗监护系统
    air530GPS数据通过air202上传阿里云
    bzoj2594: [Wc2006]水管局长数据加强版
    bzoj3091: 城市旅行
    Problem A. Array Factory XVII Open Cup named after E.V. Pankratiev Stage 4: Grand Prix of SPb, Sunday, Octorber 9, 2016
    hdu5716
    bzoj2002: [Hnoi2010]Bounce 弹飞绵羊
  • 原文地址:https://www.cnblogs.com/averson/p/5096076.html
Copyright © 2020-2023  润新知