C++中的vector是STL标准模板库提供的核心容器之一,本质是对动态数组的封装,能够在运行时自动调整自身占用的内存空间,不需要开发者手动管理内存的分配和释放,大幅降低了数组使用过程中的越界、内存泄漏等问题的发生概率。

vector的基础定义与初始化
使用vector前需要引入对应的头文件,之后可以通过多种方式定义和初始化vector对象,常见的初始化方式如下:
#include <vector>
#include <iostream>
using namespace std;
int main() {
// 定义空vector,存储int类型元素
vector<int> empty_vec;
// 定义包含5个初始值为0的int元素的vector
vector<int> init_vec1(5);
// 定义包含3个初始值为10的int元素的vector
vector<int> init_vec2(3, 10);
// 用初始化列表初始化vector
vector<int> init_vec3 = {1, 2, 3, 4, 5};
// 用另一个vector初始化新vector
vector<int> init_vec4(init_vec3);
return 0;
}
vector的常用成员函数
vector提供了丰富的成员函数来完成元素的增删改查操作,以下是开发中高频使用的函数:
| 函数名 | 功能说明 |
|---|---|
| push_back(val) | 在vector尾部添加一个元素val |
| pop_back() | 删除vector尾部的元素 |
| size() | 返回vector当前存储的元素个数 |
| capacity() | 返回vector当前分配的内存可容纳的元素个数 |
| empty() | 判断vector是否为空,为空返回true,否则返回false |
| clear() | 清空vector中的所有元素,size变为0,capacity不变 |
| at(index) | 返回索引为index的元素,会做越界检查,越界时抛出异常 |
| operator[](index) | 返回索引为index的元素,不做越界检查,效率更高 |
| insert(pos, val) | 在迭代器pos指向的位置插入元素val |
| erase(pos) | 删除迭代器pos指向的元素 |
vector的元素遍历方式
遍历vector中的元素有多种实现方式,开发者可以根据场景选择合适的遍历方法:
1. 下标遍历
利用vector支持随机访问的特性,通过下标依次访问每个元素,适合需要修改元素或者明确索引的场景:
#include <vector>
#include <iostream>
using namespace std;
int main() {
vector<int> nums = {10, 20, 30, 40, 50};
// 下标遍历
for (int i = 0; i < nums.size(); i++) {
cout << nums[i] << " ";
}
// 输出:10 20 30 40 50
return 0;
}
2. 迭代器遍历
使用vector自带的迭代器遍历元素,是STL容器的通用遍历方式,也支持在遍历过程中进行元素的插入删除操作:
#include <vector>
#include <iostream>
using namespace std;
int main() {
vector<int> nums = {10, 20, 30, 40, 50};
// 迭代器遍历
for (auto it = nums.begin(); it != nums.end(); it++) {
cout << *it << " ";
}
// 输出:10 20 30 40 50
return 0;
}
3. 范围for遍历
C++11引入的范围for语法,写法更简洁,适合只需要读取元素不需要修改的场景:
#include <vector>
#include <iostream>
using namespace std;
int main() {
vector<int> nums = {10, 20, 30, 40, 50};
// 范围for遍历
for (int num : nums) {
cout << num << " ";
}
// 输出:10 20 30 40 50
return 0;
}
vector的扩容机制
vector的动态扩容是其核心特性之一,当向vector中添加元素导致当前元素个数超过capacity()返回的容量时,vector会重新分配一块更大的内存空间,将原有元素拷贝到新空间,然后释放旧空间。不同编译器的扩容倍数不同,常见的是1.5倍或者2倍扩容。
如果提前知道vector需要存储的元素个数,可以使用reserve(n)函数预先分配至少能容纳n个元素的内存空间,减少扩容带来的性能开销:
#include <vector>
#include <iostream>
using namespace std;
int main() {
vector<int> nums;
// 预先分配可容纳10个元素的内存
nums.reserve(10);
cout << "初始capacity:" << nums.capacity() << endl; // 输出不小于10的值
return 0;
}
vector与普通动态数组的对比
普通动态数组需要开发者手动使用new和delete管理内存,容易出现内存泄漏、越界访问等问题,而vector自动管理内存,还提供了丰富的成员函数简化操作,同时支持拷贝赋值、作为函数参数传递等特性,开发效率更高。不过vector的扩容过程会有一定的性能开销,在对性能要求极高的场景下,如果元素数量固定,也可以考虑使用普通数组或者array容器。
注意:使用operator[]访问vector元素时不会做越界检查,如果访问的索引超过vector的size范围,会导致未定义行为,开发时如果不确定索引是否合法,建议使用at()函数。