【C++】vector的使用(下)

简介: 【C++】vector的使用(下)

de55415a2d79826507f38d239deb5257.png5. 数据访问


与string类似,在数据访问中也有很多接口,但是最常用的还是[]的重载,其余基本不常用,这里我们就不过多赘述

9005da39fa2134462c8e7b4a1bb404cf.png

[]实际上是一个运算符重载,使vector也具有类似下标访问的能力,返回值是vector中存放元素类型的引用

对于[]的重载,在库里面支持了两种重载,分别是普通类型的和const类型的用于支持多样化的使用环境

怎么判断需要实现const或者非const版本?

  1. 对于只读接口,只实现const版本即可
  2. 对于只写接口,只实现非const版本即可
  3. 对于可读可写的接口,需要同时实现const版本和非const版本
void Test_Access()
{
  vector<int> v(10);
  for (size_t i = 0; i < v.size(); ++i)
  {
    v[i] = i;
  }
  for (size_t i = 0; i < v.size(); ++i)
  {
    cout << v[i] << " ";
  }
  cout << endl;
}

48684b469dbc8071782d5510d539c47e.png


6. 数据修改


1. 尾插尾删

1. push_back

4d2fb4e21bd86b031e84d3d9fe2e1037.png

尾插数据,插入前会进行扩容操作,每次扩容的大小取决于编译器的实现


2. pop_back

aaa4f0e642c45ce2e741cfa33283ae57.png

如果vector中有数据的话,尾删一个数据,否则会由assert中断程序或者抛出异常,具体情况取决于编译器的实现

void Test_Modifity()
{
  vector<int> v;
  v.push_back(1);
  v.push_back(2);
  v.push_back(3);
  v.push_back(4);
  v.push_back(5);
  v.pop_back();
  v.pop_back();
  v.pop_back();
  v.pop_back();
  v.pop_back();
  v.pop_back();
}

de55415a2d79826507f38d239deb5257.png

2.任意位置的插入删除

1. insert

38c2272598b5b7694772aaaa8d4e7cd5.png

在传入的任意位置插入一个数据或者迭代器区间的数据

2. erase

9f27591d98a762ad0675b2a53aa12055.png

删除任意位置的值或者任意一个迭代器区间的值

void Test_Modifity2()
{
  vector<int> v;
  v.push_back(1);
  v.push_back(2);
  v.push_back(3);
  v.push_back(4);
  v.push_back(5);
  v.insert(v.begin() + 3, 30);
  v.erase(v.begin());
    for (auto e : v)
  {
    cout << e << " ";
  }
  cout << endl;
}


e8a039cf9f5b8939c6e689575b13822e.png

这里注意一下,vector中会出现迭代器失效的问题

❗❗==vector中的迭代器失效问题==❗❗


❓第一个问题:迭代器的出现原因是什么?


✅迭代器的设计模式,为了不暴露底层实现细节,提供统一的方式来访问容器,对于vector,其迭代器本质上就是原生指针T*,所以对vector来说,迭代器失效的原因就是原迭代器指向的空间被销毁,导致出现野指针。


❓第二个问题:导致迭代器失效的操作有哪些?


✅迭代器失效的原理是底层空间改变,导致产生野指针,所以所有的底层空间的改变都有可能使迭代器失效,例如:reserve,resize,push_back,insert等。


✅除了对底层空间的改变之外,erase也会导致迭代器失效。


❓第三个问题:按照我们上一个问题的逻辑,erase没有使底层空间发生改变啊,为什么也会使迭代器失效?


✅虽然erase没有改变底层空间,但是,如果erase删除的是vector中最后一个元素,刚好删除完之后pos位置是end指向的位置,那么迭代器就失效了。


✅就算删除的不是最后一个元素,那么迭代器指向的位置的值也是改变了的,严格意义上来说,也是不能实现我们所需要的功能的,所以也可以认为是迭代器失效了。


❓第四个问题:只有vector会遇到迭代器失效的的情况吗,string有没有迭代器失效的情况?


✅不只是vector有,string和其他的容器都有迭代器失效的情况。


❓第五个问题:迭代器失效的问题怎么解决呢?


✅在上文中,我们讲解了vector的主要接口,可以注意到,能够引起迭代器失效的接口函数的返回值都是迭代器,这里返回的迭代器就是我们所需要的有效的迭代器。所以,在使用前对迭代器进行重新赋值即可解决。

//关于迭代器失效解决的例题:
//对于使用vector存储的数组{0,1,2,3,4,5,6,7,8,9},删除其中所有的偶数元素
int main()
{
  vector<int> v(10);
  for (size_t i = 0; i < 10; ++i)
  {
    v[i] = i;
  }
  vector<int>::iterator it = v.begin();
  while (it != v.end())
  {
    if (*it % 2 == 0)
    {
      it = v.erase(it);
    }
    else
    {
      ++it;
    }
  }
  for (auto e : v)
  {
    cout << e << " ";
  }
  cout << endl;
  return 0;
}


7.其他接口


1. clear

ed6f3cbe4c38b685b94f65a82f25e10f.png

删除vector内部所有数据(本质上做的操作就是将vector的size置为0)


2. swap

5589188e14413107ae5c7d8b43f6cf54.png

vector内部实现的一个交换函数,提升效率。

相关文章
|
1月前
|
存储 编译器 C++
【C++】vector介绍+模拟实现
【C++】vector介绍+模拟实现
|
2月前
|
C++ 容器
C++中向量的操作vector
C++中向量的操作vector
|
1月前
|
算法 编译器 Linux
【C++】vector的模拟实现
【C++】vector的模拟实现
|
1月前
|
存储 算法 C语言
【C++】vector的认识与使用
【C++】vector的认识与使用
|
1月前
|
存储 算法 C++
【C++】vector介绍以及模拟实现(超级详细)
【C++】vector介绍以及模拟实现(超级详细)
42 4
|
21天前
|
C++ 索引
C++数组、vector求最大值最小值及其下标
C++数组、vector求最大值最小值及其下标
44 0
|
2月前
|
存储 C语言 C++
【C++】vector的使用上
**C++ STL的vector简介与用法:** Vector是动态顺序数组,提供高效下标访问,支持动态增长。与数组类似但可自动调整大小。常用构造函数包括默认、填充、迭代器范围和拷贝构造。析构函数自动释放内存。赋值运算符执行深拷贝。迭代器接口包括`begin()`和`end()`(反向对应`rbegin()`和`rend()`),C++11增加了const版本以支持只读访问。示例代码展示了不同构造函数和迭代器的使用。
|
3月前
|
C++ 容器
C++之评委打分案例(vector与deque容器练习)
C++之评委打分案例(vector与deque容器练习)
|
3月前
|
存储 算法 C++
C++一分钟之-容器概览:vector, list, deque
【6月更文挑战第21天】STL中的`vector`是动态数组,适合随机访问,但插入删除非末尾元素较慢;`list`是双向链表,插入删除快但随机访问效率低;`deque`结合两者优点,支持快速双端操作。选择容器要考虑操作频率、内存占用和性能需求。注意预分配容量以减少`vector`的内存重分配,使用迭代器而非索引操作`list`,并利用`deque`的两端优势。理解容器内部机制和应用场景是优化C++程序的关键。
46 5
|
3月前
|
存储 算法 C++
【C++/STL】:vector容器的基本使用
【C++/STL】:vector容器的基本使用
28 1