顺序容器初识

顺序容器定义

该类型的容器中的顺序不依赖于元素的值,而是与元素加入容器时的位置相对应。

顺序容器类型

类型 说明
vector 可变大小数组。支持随机访问。在尾部之外的位置插入或者删除元素可能较慢。
deque 双端队列。支持快速随机访问。在头尾位置插入、删除元素速度很快。
list 双向链表。只支持双向顺序访问。在list中任何位置进行插入、删除操作速度都很快。
forward_list 单向链表,只支持单向顺序访问。在链表任何位置进行插入、删除元素速度都很快。
array 固定大小数组,支持快速随机访问,不能添加或者删除元素。
string 用于专门保存字符的类似vector容器,随机访问快,在尾部插入、删除元素速度快。

问题1:
如何选择顺序容器类型?
(1)通常,使用vector作为基本容器选择。
(2)一般情况下,应用占主导地位的操作(执行的访问操作更多还是插入、删除更多)决定了容器类型的选择。

迭代器

标准容器类型上的所有迭代器都允许我们访问容器中的元素,而所有的迭代器都是通过解引用运算符来实现这个操作。

迭代器范围

迭代器范围是标准库的基础。
问题2
构成迭代器范围的迭代器有何限制?
一般采用左闭合区间[begin,end]表示范围自begin 开始,于end之前结束。迭代器begin 和end必须指向相同的容器,end 可以与begin 指向相同的位置,但不能指向begin之前的位置。

Begin 和end 成员

Begin 和end 的操作生成指向容器中第一个元素和尾元素之后位置的迭代器。这两个迭代器最常见的用途是形成一个包含容器中所有元素的迭代器范围。
Begin 和end 有多个版本:
带r的版本返回反向迭代器
带c开头的版本则返回const 迭代器
带cr的版本则返回const –反向迭代器
示例代码:

    vector<int> v1;
    const vector<int> v2;

    auto it1 = v1.begin();     //it1的类型是vector<int>::iterator
    auto it2 = v2.begin();     //it2的类型是vector<int>::const_iterator
    auto it3 = v1.cbegin();    //it3的类型是vector<int>::const_iterator
    auto it4 = v2.cbegin();    //it3的类型是vector<int>::const_iterator

表面看到的类型是在这样,我们可以看底层源码:
(1)it1的类型

auto it1 = v1.begin();     //it1的类型是vector<int>::iterator

begin () 的源码如下:

    iterator begin() _NOEXCEPT
        {   // return iterator for beginning of mutable sequence
        return (iterator(this->_Myfirst(), &this->_Get_data()));
        }

(2)it2的类型

auto it2 = v2.begin();     //it2的类型是vector<int>::const_iterator

begin() 的源码如下:

const_iterator begin() const _NOEXCEPT
        {   // return iterator for beginning of nonmutable sequence
        return (const_iterator(this->_Myfirst(), &this->_Get_data()));
        }

(3)it3的类型

auto it3 = v1.cbegin();    //it3的类型是vector<int>::const_iterator

cbegin() 的源码如下:

扫描二维码关注公众号,回复: 1730989 查看本文章
const_iterator cbegin() const _NOEXCEPT
        {   // return iterator for beginning of nonmutable sequence
        return (begin());
        }

把一个普通对象强转成常对象
(4)it4的类型

auto it4 = v2.cbegin();    //it3的类型是vector<int>::const_iterator

cbegin() 的源码

const_iterator cbegin() const _NOEXCEPT
        {   // return iterator for beginning of nonmutable sequence
        return (begin());
        }

容器定义和初始化

注意事项
将一个容器初始化为另一个容器的拷贝有两种方法:一是可以直接拷贝整个容器,或者拷贝由一个迭代器对指定的元素范围。
当将一个容器初始化为另一个容器的拷贝时,两个容器的容器类型和元素类型都必须相同。
拷贝由一个迭代器对指定的元素范围无限制,只要迭代器所指的元素可以转换即可。

赋值和swap

使用swap() 函数来交换对象中的元素

    vector<int> v1;
    vector<int> v6;
    v6.swap(v1);   //对象调用swap()函数,参数传递
    swap(v1, v6);
使用assign(仅顺序容器)

assign 允许我们从一个不同但相容的类型赋值,或者从容器的一个资讯列赋值。assign 操作用参数指定的元素(的拷贝)替换左边容器中的所有元素。

    list<string> names;
    vector<const char *> oldstyle;
    names = oldstyle;   //错误:容器类型不匹配
    names.assign(oldstyle.begin(), oldstyle.end());

猜你喜欢

转载自blog.csdn.net/u013266600/article/details/78866248
今日推荐