【C++打怪之路Lv9】-- vector

简介: 【C++打怪之路Lv9】-- vector

什么是vector


在 C++ 标准模板库(STL)中,vector 是一种序列容器,表示可以改变大小的数组

它是通过模板实现的,因此可以用于存储任何类型的对象只要这些对象支持拷贝构造函数和析构函数

vector的特点

  1. 动态数组vector 在内部使用一个动态分配的数组来存储元素。当数组满时,vector 会自动重新分配更大的内存空间,并将现有元素复制到新的内存位置。
  2. 连续存储vector 保证所有元素都存储在连续的内存位置中,这使得通过索引访问元素非常高效。
  3. 随机访问:由于元素是连续存储的,vector 支持快速随机访问,时间复杂度为 O(1)
  4. 动态大小vector 可以在运行时动态地增加或减少其大小,这是通过 push_backpop_backinserterase 等成员函数实现的。
  5. 自动内存管理vector 管理自己的内存,当 vector 被销毁或其大小被减少时,它会自动释放不再需要的内存


vector常用的函数接口


1)构造函数

①默认构造函数,创造一个空的vector容器

vector();

②构造一个vector类对象并用n个val初始化

vector(size_t n, const value_type& val);

创建一个包含 n 个元素的 vector,并且所有元素都是初始值 val 使用

注:value_typevector 存储元素的类型

③拷贝构造函数

vector(const vector& other);

创建一个新 vector 作为另一个已存在 vector 的副本使用

④使用迭代器进行初始化构造

template <class InputIterator>
vector(InputIterator first, InputIterator last);

使用迭代器指定的范围来初始化 vector 时使用,这个范围包括 [first, last) 中的元

注:InputIterator 是一种迭代器类型,它可以是任何能够用于迭代的类型,比如指针或者其它容器的迭代器

2)容量操作

①size

size_t size() const;

获取vector中元素个数

②capacity

size_t capacity() const;

获取vector当前容量( vector 在不重新分配内存的情况下可以容纳的最大元素数量)

③empty

bool empty() const;

检查vector是否为空

④resize

void resize(size_t n, value_type val = value_type());

改变vector的大小,多出来的会填充默认值

用来调整 vector 的大小到 n 个元素。

①如果 n 小于当前大小,则删除多余的元素;

②如果 n 大于当前大小,则添加新元素,并用 val 初始化它们

⑤reverse

void reserve(size_t n);

设置vector的容量

用来预留至少能够容纳 n 个元素的内存空间。这不会改变 vector 的 size,但会增加其 capacity

 

3)访问和遍历

operator[]

reference operator[](size_t n);
const_reference operator[](size_t n) const;

访问vector中的元素

通过索引 n 访问 vector 中的元素。不检查索引是否有效,因此使用时需确保索引在有效范围内

注:referenceconst_reference 分别表示对 vector 元素的引用和常量引用

②迭代器(正向和反向迭代器)

iterator begin();
const_iterator begin() const;
iterator end();
const_iterator end() const;
reverse_iterator rbegin();
const_reverse_iterator rbegin() const;
reverse_iterator rend();
const_reverse_iterator rend() const;

遍历vector中的元素

③at

reference at(size_type n);
const_reference at(size_type n) const;

访问vector中的元素,并提供边界检查

通过索引 n 安全地访问 vector 中的元素。如果索引无效,则抛出 std::out_of_range 异常

④front and back

reference front();
const_reference front() const;
reference back();
const_reference back() const;

front -- 访问vector的第一个元素

back -- 访问vector的最后一个元素

[如vector为空,则行为未定义]

4)vector的增删查改

①push_back

void push_back(const value_type& val);

在vector的末尾添加一个元素,如果需要,会自动增加 vector 的容量

②pop_back

void pop_back();

删除vector末尾的元素

③find

template <typename InputIterator, typename T>
InputIterator find(InputIterator first, InputIterator last, const T& val);

find查找两个迭代器区间的val值

find不是vector的成员函数

④insert

iterator insert(const_iterator position, const value_type& val);
iterator insert(const_iterator position, size_type n, const value_type& val);
template <class InputIterator>
iterator insert(const_iterator position, InputIterator first, InputIterator last);

在迭代器 插入1个 或多个元素 或一个vector类对象

 

⑤erase

iterator erase(const_iterator position);
iterator erase(const_iterator first, const_iterator last);

⑥swap

void assign(size_type n, const value_type& val);
template <class InputIterator>
void assign(InputIterator first, InputIterator last);

⑦assign

void assign(size_type n, const value_type& val);
template <class InputIterator>
void assign(InputIterator first, InputIterator last);

为vector指定新内容

⑧clear

void clear() noexcept;

清空,size为0


什么是迭代器失效


迭代器的失效是指由于容器的修改操作,使得原有迭代器不再有效无法正确访问容器元素

简单来说:

迭代器失效就像是你拿着指向某个物品的指针,但物品的位置变了,你的指针就找不到原来的物品了

通常发生在以下几种情况:


  1. 容器内存重新分配:当容器如 vector 或 string 因为增加元素而需要重新分配内存时,之前指向容器元素的迭代器、指针和引用会失效。
  1. 容器元素删除:当通过 erase、clear 或 pop_back 等操作从容器中删除元素时,指向被删除元素或被删除元素之后元素的迭代器会失效。
  1. 容器插入操作:在序列容器(如 vector、deque、string)中插入元素可能会使插入点之后的所有迭代器失效


如何避免迭代器失效

专业术语:

1、重获迭代器:在容器修改操作后,使用返回的有效迭代器更新现有迭代器。

2、范围删除:使用基于范围的 erase 方法来删除元素,避免单独删除导致的迭代器失效。

3、避免失效操作:了解哪些容器操作会导致迭代器失效,并尽量规避。

简单来讲:

更新指针:当你删除或添加元素后,记得重新获取新的迭代器位置。

一次性清理:如果需要删除多个元素,尽量一次性完成,而不是一个一个删。

别用坏指针:知道哪些操作会让迭代器变坏,就不要在那些操作后继续使用旧的迭代器。

总结

避免迭代器失效的关键在于

操作后更新迭代器,批量处理元素,以及避免使用已失效的迭代器

目录
相关文章
|
1月前
|
存储 编译器 对象存储
【C++打怪之路Lv5】-- 类和对象(下)
【C++打怪之路Lv5】-- 类和对象(下)
27 4
|
1月前
|
编译器 C语言 C++
【C++打怪之路Lv4】-- 类和对象(中)
【C++打怪之路Lv4】-- 类和对象(中)
23 4
|
1月前
|
存储 算法 调度
【C++打怪之路Lv11】-- stack、queue和优先级队列
【C++打怪之路Lv11】-- stack、queue和优先级队列
33 1
|
1月前
|
存储 算法 C++
【C++打怪之路Lv10】-- list
【C++打怪之路Lv10】-- list
20 1
|
1月前
|
存储 安全 C++
【C++打怪之路Lv8】-- string类
【C++打怪之路Lv8】-- string类
21 1
|
1月前
|
编译器 程序员 C++
【C++打怪之路Lv7】-- 模板初阶
【C++打怪之路Lv7】-- 模板初阶
16 1
|
1月前
|
存储 C语言 C++
【C++打怪之路Lv6】-- 内存管理
【C++打怪之路Lv6】-- 内存管理
37 0
【C++打怪之路Lv6】-- 内存管理
|
1月前
|
安全 测试技术 C++
【C++篇】从零实现 C++ Vector:深度剖析 STL 的核心机制与优化2
【C++篇】从零实现 C++ Vector:深度剖析 STL 的核心机制与优化
61 6
|
1月前
|
编译器 C++
【C++】—— vector模拟实现
【C++】—— vector模拟实现
|
1月前
|
存储 编译器 C语言
【C++打怪之路Lv3】-- 类和对象(上)
【C++打怪之路Lv3】-- 类和对象(上)
16 0