vector
是C++标准模板库(STL)中最常用的序列容器之一,它提供了动态数组的功能,可以方便地进行元素的添加、删除和访问操作。与普通数组不同,vector
的大小是可以动态调整的,因此在使用时不需要提前知道数组的确切大小。
1. vector
概述
vector
是一个模板类,定义在<vector>
头文件中。它的底层实现是一个动态数组,这意味着vector
在需要时会自动调整其容量(capacity)以适应新的元素。vector
的特点包括:
- 动态大小:
vector
会自动管理内存,在需要时自动扩展或收缩。 - 连续存储:
vector
的元素存储在连续的内存块中,这使得vector
可以有效地使用指针和偏移量来访问元素。 - 随机访问:
vector
支持常数时间复杂度的随机访问,类似于C风格数组。
2. 基本使用
在C++中使用vector
非常简单,以下是一些常见的操作示例:
#include <iostream>
#include <vector>
int main() {
// 定义一个存储整数的vector
std::vector<int> vec;
// 添加元素
vec.push_back(10);
vec.push_back(20);
vec.push_back(30);
// 访问元素
std::cout << "vec[1] = " << vec[1] << std::endl; // 输出 20
// 遍历vector
for (size_t i = 0; i < vec.size(); ++i) {
std::cout << "vec[" << i << "] = " << vec[i] << std::endl;
}
// 删除最后一个元素
vec.pop_back();
return 0;
}
常见成员函数
push_back(const T& value)
:在末尾添加元素。pop_back()
:移除末尾的元素。size()
:返回当前存储的元素个数。capacity()
:返回当前分配的容量。resize(size_t n)
:调整容器大小。clear()
:清空容器。
3. 底层实现原理
vector
的底层实现是一个动态数组。当vector
的容量不足以容纳新元素时,它会自动分配一块更大的内存空间,并将现有的元素复制到新内存中。为了减少内存重新分配的次数,vector
通常会按照一定的增长策略(例如翻倍)来分配内存。
关键点:
- 容量与大小:
size()
返回的是当前元素的个数,而capacity()
返回的是当前分配的内存可以容纳的元素个数。capacity
通常大于或等于size
。 - 内存增长策略:
vector
的容量按照一定比例增长,以降低频繁的内存分配开销。常见的增长策略是每次扩展容量为当前的1.5到2倍。 - 指针失效:由于内存重新分配会导致元素的物理地址变化,因此在向
vector
中添加或删除元素后,先前的指针或引用可能会失效。
4. 常用操作
插入与删除
除了push_back()
和pop_back()
,vector
还提供了灵活的插入与删除操作,例如:
#include <iostream>
#include <vector>
int main() {
std::vector<int> vec = {1, 2, 3, 4, 5};
// 插入元素
vec.insert(vec.begin() + 2, 10); // 在第3个元素前插入10
// 删除元素
vec.erase(vec.begin() + 1); // 删除第2个元素
return 0;
}
迭代器
vector
提供了标准的迭代器接口,可以方便地进行遍历、插入和删除操作。迭代器包括begin()
、end()
、rbegin()
、rend()
等。
#include <iostream>
#include <vector>
int main() {
std::vector<int> vec = {1, 2, 3, 4, 5};
// 使用正向迭代器遍历
for (auto it = vec.begin(); it != vec.end(); ++it) {
std::cout << *it << " ";
}
std::cout << std::endl;
// 使用反向迭代器遍历
for (auto rit = vec.rbegin(); rit != vec.rend(); ++rit) {
std::cout << *rit << " ";
}
std::cout << std::endl;
return 0;
}
5. 性能优化建议
尽管vector
在大多数情况下表现良好,但仍有一些优化技巧可以帮助提高性能:
-
预先分配内存:如果已知
vector
的最终大小,可以使用reserve()
函数预先分配内存以避免多次分配和拷贝。 -
避免频繁的插入与删除:由于
vector
在插入和删除元素时可能会移动大量元素,因此在需要频繁进行插入删除操作时,考虑使用deque
或list
。 -
使用
shrink_to_fit()
:在删除大量元素后,可以使用shrink_to_fit()
函数来释放不再需要的内存。
#include <iostream>
#include <vector>
int main() {
std::vector<int> vec(1000, 0);
// 删除大量元素
vec.erase(vec.begin(), vec.end() - 100);
// 收缩容量
vec.shrink_to_fit();
return 0;
}
结语
vector
作为C++中的一个基础容器类,因其灵活性和高效性被广泛使用。通过了解其底层实现原理和性能特点,可以更好地利用vector
,编写出高效、健壮的代码。
希望这篇博客对你深入理解和使用vector
有所帮助!