std::vector
是 C++ STL 中最核心的动态数组容器,支持高效随机访问和动态扩容。本文从 基础用法 和 深度优化 两个维度,系统解析其构造函数、迭代器、容量管理、元素访问和修改操作,涵盖函数重载、参数差异及相似函数对比,并提供丰富的代码示例。
vector<T> vec;
vector<T> vec(n, val);
vector<T> vec(n)
:创建包含 n
个默认初始化元素的容器(如 int
初始化为 0)。 vector<T> vec(n, val)
:创建包含 n
个值为 val
的元素的容器。 vector<T> vec(iter_start, iter_end);
vector
。 vector<T> vec{1, 2, 3};
函数 | 功能 | 示例 |
---|---|---|
| 返回指向第一个元素的迭代器 |
|
| 返回指向末尾(最后一个元素之后)的迭代器 |
|
| 返回反向迭代器(从末尾开始遍历) |
|
| 返回反向迭代器的结束位置 |
|
函数 | 功能 | 示例 |
---|---|---|
| 返回常量正向迭代器 |
|
| 返回常量正向迭代器的结束位置 |
|
| 返回常量反向迭代器 |
|
| 返回常量反向迭代器的结束位置 |
|
示例:
std::vector<int> vec = {10, 20, 30};
// 正向遍历
for (auto it = vec.begin(); it != vec.end(); ++it) {
std::cout << *it << " "; // 输出:10 20 30
}
// 常量反向遍历
for (auto crit = vec.crbegin(); crit != vec.crend(); ++crit) {
std::cout << *crit << " "; // 输出:30 20 10
}
函数 | 功能 | 示例 |
---|---|---|
| 返回当前元素数量 |
|
| 返回已分配的内存容量 |
|
| 检查容器是否为空 |
|
resize(n, val)
vs resize(n)
resize(5)
:若原大小为 3,新增 2 个默认值元素(如 int
为 0)。 resize(5, 10)
:新增的 2 个元素值为 10。 n < size()
,超出部分的元素被销毁,但 容量不变。 n>capacity()
,将会引发扩容示例:
std::vector<int> vec = {1, 2, 3};
vec.resize(5); // {1, 2, 3, 0, 0}
vec.resize(3); // {1, 2, 3}(容量仍可能为 5)
vec.resize(5, 10); // {1, 2, 3, 10, 10}
reserve(n)
vs shrink_to_fit()
reserve(n)
:预分配至少 n
个元素的内存,避免频繁扩容。 shrink_to_fit()
:请求释放未使用的内存,但 不保证容量等于 size()
。 ==该函数谨慎使用== 因为动态申请的内存不支持分段释放,缩容实际上是开辟了新的空间,释放了原有的空间,会有一定的效率牺牲示例:
std::vector<int> vec;
vec.reserve(100); // 容量为 100
vec.push_back(1);
vec.shrink_to_fit(); // 容量可能变为 1(具体由实现决定)
特性 |
|
|
---|---|---|
越界检查 | assert断言 | 有(抛出 |
性能 | 更高(直接访问) | 略低(需检查) |
适用场景 | 已知索引安全时 | 需要异常处理的场景 |
示例:
std::vector<int> vec = {10, 20, 30};
int a = vec[3]; // 未定义行为(可能崩溃或返回垃圾值)
int b = vec.at(3); // 抛出异常:std::out_of_range
函数 | 功能 | 示例 |
---|---|---|
| 访问第一个元素 |
|
| 访问最后一个元素 |
|
对比 front()
和 begin()
:
front()
返回元素引用,begin()
返回迭代器。 std::vector<int> vec = {1, 2, 3};
vec.front() = 10; // 直接修改首元素
auto it = vec.begin();
*it = 20; // 通过迭代器修改data()
T* data();
函数 | 功能 | 示例 |
---|---|---|
| 在末尾添加元素(可能触发拷贝/移动) |
|
| 直接在末尾构造元素(避免临时对象) |
|
| 删除末尾元素 |
|
push_back
vs emplace_back
:
push_back
:需构造临时对象,再拷贝或移动到容器。 emplace_back
:直接通过参数在容器内构造对象,效率更高。 示例:
class Data {
public:
Data(int a, double b) { /* ... */ }
};
std::vector<Data> vec;
vec.push_back(Data(1, 2.0)); // 构造临时对象,再移动
vec.emplace_back(1, 2.0); // 直接在容器内构造
insert
的多个重载版本erase
的用法函数 | 功能 | 示例 |
---|---|---|
| 替换容器内容 |
|
| 清空所有元素(容量不变) |
|
| 交换两个容器的内容 |
|
assign
的重载版本:
std::vector<int> vec;
vec.assign(3, 5); // {5, 5, 5}(填充 n 个值)
vec.assign({1, 2, 3}); // {1, 2, 3}(初始化列表)
std::list<int> lst = {7, 8};
vec.assign(lst.begin(), lst.end()); // {7, 8}(迭代器范围)
vector<T> vec;
,预分配内存用 vector(n)
,列表初始化用 {}
。 reserve()
,可以减少频繁扩容的效率降低 operator[]
,需异常处理时用 at()
。 emplace_back
减少拷贝,批量插入用 insert
的重载版本。 cbegin()/cend()
,反向遍历用 rbegin()/rend()
。 通过合理选择函数重载和参数,可以显著提升代码的效率和健壮性。
本文完
下篇文章将为读者讲解vector的底层原理和模拟实现
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。