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


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

一、构造方法

构造函数

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

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

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

n个T类型构造

vector<int> v3(5, 1);

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

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

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

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

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

拷贝构造函数

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

在这里插入图片描述

二、迭代器与元素访问

迭代器

  • 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] << " ";
}

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

//auto it = v.begin();
vector<int>::iterator it = v.begin();
for (it; it != v.end(); it++)
{
	cout << *it << " ";
}

反向迭代器

//auto rit = v.rbegin();
vector<int>::reverse_iterator rit = v.rbegin();
for (rit; rit != v.rend(); rit++)
{
	cout << *rit << " ";
}

范围for

for (auto e : v)
{
	cout << e << " ";
}

三、容量相关

  • 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);

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

swap引起的迭代器失效

在这里插入图片描述

解决方法

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

六、动态二维数组

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

  • 10
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 8
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值