• vector接口介绍&迭代器失效问题



    注:主要介绍部分常用及重点接口

    一、构造方法

    构造函数

    无参构造
    一般使用这种空的vector对象要进行push_back或者调用resize进行扩容

    vector<int> v1;//构造一个空对象
    
    • 1

    无参构造的对象,size和capacity都为0:
    在这里插入图片描述

    n个T类型构造

    vector<int> v3(5, 1);
    
    • 1

    结果如图:
    在这里插入图片描述

    迭代器区间构造
    构造一个vector类对象

    string s1("Hello");
    vector<char> v5(s1.begin(), s1.begin() + 2);
    
    • 1
    • 2

    在这里插入图片描述
    关于T()的问题

    调用n个T类型构造方方法进行构造时,如果第二个参数没有给出,会用默认的T()填充对用内置类型,T()的值都为0自定义类型则会调用默认的构造函数,而如果该自定义类型没有默认的构造函数,程序会报错,如图:
    在这里插入图片描述

    拷贝构造函数

    vector<int> v1(3, 1);
    vector<int> v2(v1);//调用拷贝构造函数
    
    • 1
    • 2

    在这里插入图片描述

    二、迭代器与元素访问

    迭代器

    • begin&end 获取第一个数据位置的iterator,最后一个数据下一个位置的迭代器
    • rbegin + rend 获取最后一个数据位置的reverse_iterator,获取第一个数据前一个位置的reverse_iterator
    • cbegin、cend、crbegin、crend这四个是const类型的迭代器,可以访问const成员变量
    • operator[] 通过下标访问,与at的区别是,operator[]底层通过assert处理越界,而at访问越界会抛出异常
      在这里插入图片描述

    访问方式

    下标访问

    vector<int> v{ 0,1,2,3,4,5 };
    for (int i = 0; i < v.size(); i++)
    {
    	cout << v[i] << " ";
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    迭代器访问
    可以使用auto定义变量

    //auto it = v.begin();
    vector<int>::iterator it = v.begin();
    for (it; it != v.end(); it++)
    {
    	cout << *it << " ";
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    反向迭代器

    //auto rit = v.rbegin();
    vector<int>::reverse_iterator rit = v.rbegin();
    for (rit; rit != v.rend(); rit++)
    {
    	cout << *rit << " ";
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    范围for

    for (auto e : v)
    {
    	cout << e << " ";
    }
    
    • 1
    • 2
    • 3
    • 4

    三、容量相关

    • size 有效元素个数
    • capacity 容量大小
    • empty 判断是否为空
    • resize 改变size大小
    • reserve 扩容

    vector扩容机制

    VS2022

    VS中使用的是PJ版本的STL,capacity是按1.5倍进行扩容的
    在这里插入图片描述

    g++

    g++使用的是SGI版的STL,按照2倍进行扩容
    在这里插入图片描述

    四、内容修改接口

    • push_back 尾插
    • pop_back 尾删
    • assign 重新分配
    • insert 任意位置插入
    • erase 任意位置删除
    • swap 交换连个vector对象的空间
    • clear 清空对象内容

    swap的使用,在交换两个vector类对象时,尽可能使用vector类内置的swap函数,因为内置的交换函数效率更高,使用swap函数模板交换时会定义临时变量,效率较低。

    五、关于vector的迭代器失效问题

    什么是迭代器失效

    迭代器的主要作用就是让程序不关心底层的数据结构,其底层实际就是一个指针或者对指针进行封装,在vector中,迭代器就是原生态的指针T*类型。而迭代器失效,实际就是迭代器底层对应的指针所指向的空间被销毁,而使用了一块被释放的空间,会导致程序崩溃。
    会引起底层空间改变的操作,都有可能导致迭代器失效

    迭代器失效验证

    改变底层空间

    以push_back为例:
    在这里插入图片描述
    在上面的程序中,迭代器it指向vector类对象v的起始位置,调用push_back进行尾插之后,v底层空间不够进行了扩容操作,而扩容操作的一般步骤是:开辟新空间,拷贝元素,释放旧空间;执行完这三步以后,v中的元素已经被拷贝到了新的空间,而迭代器it指向的旧空间已经被释放,再次对it进行操作时,会访问到已经释放的空间,而引起程序崩溃。
    除了push_back外,resize、reserve、insert、assign、operator=这些操作都有可能导致迭代器失效。

    erase引起的迭代器失效

    • VS2022中
      在这里插入图片描述
    • g++
      在这里插入图片描述

    在两种编译环境中,erase删除当前位置元素后,编译器都会让指向当前位置的迭代器失效。而erase删除当前位置元素后会返回下一个位置的迭代器

    iterator erase (iterator position);
    iterator erase (iterator first, iterator last);
    
    • 1
    • 2

    在这里插入图片描述
    所以解决的办法就是用it接收erase的返回值:
    在这里插入图片描述

    swap引起的迭代器失效

    在这里插入图片描述

    解决方法

    迭代器失效的解决方法:在使用前,对迭代器进行重新赋值,对于上文push_back的程序作修改:
    在这里插入图片描述
    无论迭代器在何处定义,使用前都重新进行赋值,避免迭代器失效的问题。

    六、动态二维数组

    杨辉三角
    在这里插入图片描述
    矩阵
    在这里插入图片描述

  • 相关阅读:
    【Vue五分钟】 Vue Cli脚手架安装配置
    30.3.2 使用GRANT语句为用户授权
    docker镜像的创建
    global和nonlocal混合使用
    第一季:2单例设计模式【Java面试题】
    计算机视觉(三):基于Scipy图像处理技术,图像模糊(灰色、彩色图像高斯模糊)、图像导数(sobel算子滤波)
    Git/GitHub/Idea的搭配使用
    推荐基于.NetCore一款高性能敏感词检测开源库
    C_plus_侯捷课件笔记
    解决阿里云服务器使用ip访问Nginx失败的问题
  • 原文地址:https://blog.csdn.net/qq_44631587/article/details/126330137