前言:
vector
是标准模板库(STL)中非常常用的一种动态数组容器。它结合了数组的高效访问特性和动态数组的灵活性,能够自动调整大小以适应元素的增减,是处理可变数量序列数据的理想选择。
一、vector
详解
1、内存管理
vector
的内存管理是其核心特性之一,它基于动态内存分配,能够根据需要自动扩展或收缩其容量。
- 动态大小:
vector
能够在运行时动态地增加或减少其容量,以适应元素的数量变化,无需程序员显式地管理内存。当向vector添加元素导致当前容量不足以容纳新元素时,vector
会自动重新分配内存,通常是原容量的一定倍数(如加倍),以减少频繁的内存重分配。 - 连续存储: 尽管
vector
可以动态调整大小,但其元素在内存中是连续存储的,这使得它支持快速随机访问,类似于传统的数组。
2、初始化
vector<T>()
:默认构造函数,创建一个空的vector
。vector<T>(n, val)
:创建包含n个值为val的元素的vector
。vector<T>(const vector<T>& x)
:拷贝构造函数,创建x的一个副本。
3、添加
push_back()
: 此方法将一个已构造的对象或临时对象复制或移动到容器的末尾。它首先创建一个对象,然后将该对象拷贝或移动到容器中。emplace_back()
: 此方法直接在容器末尾构造对象,避免了不必要的复制或移动操作。它通过传递构造函数的参数来直接创建对象,从而减少了一次对象的构造和析构过程。
4、删除
erase()
: 该方法是删除std::vector
中元素的标准方式。它接受一个迭代器(指向要删除的元素)或一对迭代器(指向要删除的元素范围),并删除这些元素。删除元素后,所有后续元素都会向前移动以填补空白。remove()
或remove_if()
: 这两个是算法库中的函数,它们并不真正地从std::vector
中删除元素,而是将不需要的元素移动到容器的末尾,并返回一个指向新逻辑末尾的迭代器。该方法并不改变容器的大小,只是重新排列元素,然后,可以使用vector::erase()
来删除这些“被移动”的元素。clear()
: 清空容器中的元素,重置容器的大小为 0,但保留其容量。
示例:删除容器中指定的元素(容器中的元素是自定义类型)
class Person {
public:
std::string name;
int age;
Person(std::string n, int a) : name(n), age(a) {}
// 用于输出的友元函数
friend std::ostream& operator<<(std::ostream& os, const Person& p) {
os << "Name: " << p.name << ", Age: " << p.age;
return os;
}
};
// 一个用于删除特定姓名的Person的函数
void removePersonByName(std::vector<Person>& vec, const std::string& nameToRemove) {
// 使用std::remove_if删除所有name等于nameToRemove的Person对象
// 注意:remove_if并不真正从vector中删除元素,而是将它们移到vector的末尾
// 并返回一个指向新逻辑末尾的迭代器
auto newEnd = std::remove_if(vec.begin(), vec.end(),
[nameToRemove](const Person& p) {
return p.name == nameToRemove;
}
);
// 使用erase来实际删除这些元素
vec.erase(newEnd, vec.end());
}
int main() {
std::vector<Person> people = {
{"Alice", 30},
{"Bob", 25},
{"Charlie", 35},
{"Alice", 22} // 假设我们想要删除这个Alice
};
std::cout << "Before removal:\n";
for (const auto& p : people) {
std::cout << p << std::endl;
}
// 删除 Alice
removePersonByName(people, "Alice");
std::cout << "\nAfter removal:\n";
for (const auto& p : people) {
std::cout << p << std::endl;
}
return 0;
}
5、查找
std::find()
: 在指定范围内查找符合要求的元素,适用于查找与给定值完全相等的元素。std::find_if()
: 在指定范围内查找符合要求的元素,允许使用一个谓词(这里是一个lambda表达式)来定义查找条件,当容器存储的是自定义类型时,使用该方法比较合适。
6、遍历
- 使用传统的for循环,需要元素的索引时,比较适合采用该方法。
- 使用范围基的for循环(C++11及更高版本)。
- 使用迭代器。
7、常用操作
size()
: 返回vector
中元素的数量。empty()
: 检查vector
是否为空。capacity()
: 返回vector
当前分配的存储空间容量(可能大于size()
)。reserve(size_t n)
: 请求vector
的容量至少为 n,以优化内存分配。push_back(const T& value)
: 在vector
的末尾添加一个元素。pop_back()
: 移除vector
的最后一个元素。insert(iterator pos, const T& value)
: 在指定位置插入一个元素。erase(iterator pos)
: 移除指定位置的元素。erase(iterator first, iterator last)
: 移除指定范围内的元素。clear()
:移除vector
中的所有元素。resize(size_t n, T value = T())
:改变vector
的大小,如果新大小大于当前大小,则用给定值填充新元素。front()
: 返回vector
的第一个元素的引用。back()
: 返回vector
的最后一个元素的引用。begin()
: 返回指向vector
第一个元素的迭代器。end()
: 返回指向vector
最后一个元素之后位置的迭代器(即“尾后迭代器”)。