😇 😇各位小伙伴们,大家好!我是bug。今天我们来谈谈vector的相关内容:
(代码可能会有一点问题,请各位老铁指正 😘 😘 )
文章目录
一、vector的概念
🍉 🍉 Vector: vector是C++标准模板库中的部分内容。它是动态增长的对象数组,它是一个多功能的,能够操作多种数据结构和算法的模板类和函数库。
二、vector的用法
🌹 🌹 vector的常用接口:
construct(构造函数) | 用法 |
---|---|
vector() | 无参构造函数 |
vector(size_type n, const value_type& val = value_type()) | 构造初始化n个val |
vector (const vector& x); | 拷贝构造 |
vector (InputIterator first, InputIterator last); | 迭代器初始化构造 |
遍历操作 | 用法 |
---|---|
operator[] | 数组 |
begin | 获取第一个数据位置的iterator/const_iterator |
end | 获取最后一个数据的下一个位置的iterator/const_iterator |
rbegin | 获取最后一个数据位置的reverse_iterator |
rend | 获取第一个数据前一个位置的reverse_iterator |
操作空间/容量 | 用法 |
---|---|
size | 获取数据个数 |
capacity | 获取容量大小 |
empty | 判断是否为空 |
resize | 改变vector的size |
reserve | 改变vector的capacity |
修改操作 | 用法 |
---|---|
push_back | 尾插 |
pop_back | 尾删 |
insert | 在position之前插入数据 |
erase | 删除position位置的数据 |
swap | 交换两个vector的数据空间 |
🌳(1)vector对象的创建
vector创建对象的方式有很多,比如:
🌵 使用默认构造函数
🌵 使用带参构造函数
🌵 使用拷贝构造函数
🌵 使用赋值运算符重载
🌵 使用迭代器区间进行构造
🌵 创建匿名对象
🍒 🍒代码⬇️ ⬇️:
//有参数构造
vector<int> v1(5, 4);
//无参数构造
vector<int> v2;
//拷贝构造
vector<int> v3(v1);
//迭代器区间进行构造
vector<int> v4(v1.begin(), v1.end());
//赋值运算符重载
vector<int> v5 = v1;
//匿名对象
vector<int>();
🌳(2)vector的遍历
string有三种遍历的方式:
🌵 通过[]的重载像数组一样遍历。
🌵 通过迭代器进行遍历。
🌵 通过范围for进行的遍历
🍒 🍒代码⬇️ ⬇️:
//遍历,和string类似,这里就不详细演示了
vector<int> v(4, 5);
//[]重载
for (size_t i = 0; i < v.size(); i++)
{
cout << v[i] << " ";
}
cout << endl;
//迭代器
vector<int>::iterator it = v.begin();
while (it != v.end())
{
cout << *it << " ";
it++;
}
cout << endl;
//范围for
for (auto e : v)
{
cout << e << " ";
}
cout << endl;
注意❗️ ❗️
🌱 (1)[]的重载有const和非const版本的。
🌱 (2)迭代器有const和非const版本的,C98中直接将begin、end进行重载。在C11中为了区别const和非const迭代器,引入了cbegin和cend。(和begin、end的const版本就名字不同)
🌱 (3)范围for的本质是迭代器,程序运行过程中,编译器会把范围for替换成迭代器进行操作。同时范围for是通过赋值的方式进行遍历(将数据赋给变量),如果要修改,就要使用引用。
🌳(3)vector的reserve和resize
🍒 🍒测试代码⬇️ ⬇️:
vector<int> v(4, 5);
//打印容量
cout << v.capacity() << endl;
v.reserve(3);
cout << v.capacity() << endl;
v.reserve(8);
cout << v.capacity() << endl;
//只能扩容,和string一样
v.resize(2);
//打印容量
cout << v.capacity() << endl;
//遍历
auto it = v.begin();
while (it != v.end())
{
cout << *it << " ";
it++;
}
cout << endl;
v.resize(12, 0);
//要重新对it赋值,因为扩容之后迭代器begin发生了改变
//这里的begin是原生指针
it = v.begin();
//打印容量
cout << v.capacity() << endl;
while (it != v.end())
{
cout << *it << " ";
it++;
}
cout << endl;
🌳(4)迭代器失效问题****
迭代器失效有两种情况:
🍎 1.、会引起其底层空间改变的操作,都有可能是迭代器失效,比如:resize、reserve、insert、assign、push_back等。
🍎 2、erase删除数据
解决方法:对it重新赋值。
🍔 🍔这里我们来仔细谈谈迭代器失效:
在vector的类中,我们并没有实现find函数,我们使用的是算法里面的查找函数,当我们使用insert进行插入、或者使用erase删除等操作时,都需要找到数据的位置然后进行相应的操作。
但是会有这几种情况发生:
🍁 (1)使用insert等接口时,底层空间发生了改变。
从底层的角度我们不难发现,以扩容为例,过程大致分为这么几个步骤: