【C++】vector常用方法总结

📝前言:

C++中string常用方法总结中我们讲述了string的常见用法,vector中许多接口与string类似,作者水平有限,所以这篇文章我们主要通过读vector官方文档的方式来学习vector中一些较为常见的重要用法。

🎬个人简介:努力学习ing

📋个人专栏:C++学习笔记

🎀CSDN主页 愚润求学

🌄其他专栏:C语言入门基础python入门基础python刷题专栏


vector常见方法

  • 一,vector的定义
    • [1. vector的构造函数](#1. vector的构造函数)
    • [2. 迭代器](#2. 迭代器)
    • [3. 容量操作](#3. 容量操作)
    • [4. 增删查改操作](#4. 增删查改操作)
    • [5. 迭代器失效问题](#5. 迭代器失效问题)
      • [5.1. 插入元素引发的迭代器失效](#5.1. 插入元素引发的迭代器失效)
      • [5.2. 删除元素导致的迭代器失效](#5.2. 删除元素导致的迭代器失效)
      • [5.3. 调整容器大小引起的迭代器失效](#5.3. 调整容器大小引起的迭代器失效)
      • [5.4. 避免迭代器失效的方法](#5.4. 避免迭代器失效的方法)
        • [1. 插入元素时](#1. 插入元素时)
        • [2. 删除元素时](#2. 删除元素时)
        • [3. 调整容器大小时](#3. 调整容器大小时)
    • [6. 小知识点补充](#6. 小知识点补充)

一,vector的定义

vector原型:template < class T, class Alloc = allocator<T> > class vector; // generic template

也就是说vector是一个模板,T可以是任意类型,如intstring,甚至是vector<int>(此时是一个二维数组)

特点

  • 动态大小:vector可以在运行时按需调整大小,可以添加或移除元素。
  • 随机访问:能在常数时间内通过索引访问任意元素。
  • 连续存储:元素在内存中连续存储
  • 自动内存管理:vector会自动处理内存分配和释放

1. vector的构造函数

const allocator_type& alloc = allocator_type()是一个有关内存分配的参数,它的作用是指定 vector 所使用的内存分配器。内存分配器负责管理 vector 内部元素存储所需的内存。(在这里我们先不管它)

  1. vector()是vector的无参默认构造,会创建一个空的vector对象
  2. vector (size_type n, const value_type& val = value_type())构造并初始化nval
    这里的value_type()是调用value_type的构造函数,用匿名对象来初始化val。(对于内置类型,为了统一,内置类型也会有默认构造,不过默认构造不做任何处理,如:int a = int()这里相当于用0来初始化a
  3. vector (InputIterator first, InputIterator last)用区间迭代器初始化构造(注意是左闭右开原则)
  4. vector (const vector& x)拷贝构造(深拷贝)

2. 迭代器

vector也有和string类似的迭代器,值得注意的是endrend的位置

3. 容量操作

接口 接口说明
size 获取元素个数
capacity 获取容量大小
empty 判断是否为空
reserve 改变capacity
resize 改变size

这些接口和方法的特性和string一样就不过多赘述

4. 增删查改操作

接口 接口说明
push_back 尾插
pop_back 尾删
find 查找
insert 在position插入val(原来position位置的元素后移)
erase 从position位置开始删除数据
swap 交换两个vector的数据空间
operator[] 像数组一样访问

注意find是算法模块实现,不是vector的成员接口。这些接口和方法的特性和string一样就不过多赘述

5. 迭代器失效问题

在使用vector的迭代器时,若容器的底层空间改变 (如扩容),就可能导致迭代器失效

迭代器失效就是:迭代器已经不是指向原来的数据,此时意义发生改变(可能指向别的位置,也可能是随机值)

迭代器失效后,我们就不能访问原来已经失效的的迭代器。在vs中会强制检查,访问即报错,但是在Linux中不强制检查。

5.1. 插入元素引发的迭代器失效

当在vector里插入元素时,若insert操作致使容器重新分配内存(扩容),那么所有指向该容器的迭代器都会失效。这是因为重新分配内存时,容器中的元素会被移动到新的内存位置,而原来的迭代器依旧指向旧的内存地址,原来的地址又被释放,此时就指向随机值了(类似野指针)。

cpp 复制代码
#include <iostream>
#include <vector>

int main() {
    std::vector<int> vec = {1, 2, 3};
    auto it = vec.begin();
    // 插入元素可能导致内存重新分配
    vec.insert(vec.begin(), 0); 
    // 此时 it 已经失效,不能再使用
    // std::cout << *it << std::endl; // 错误:使用失效的迭代器
    return 0;
}

5.2. 删除元素导致的迭代器失效

vector中删除元素时,被删除元素及其后面的所有迭代器都会失效。因为删除元素后,后面的元素会向前移动填补空缺,原有的迭代器指向的位置不再正确。

cpp 复制代码
#include <iostream>
#include <vector>

int main() {
    std::vector<int> vec = {1, 2, 3};
    auto it = vec.begin() + 1;
    // 删除元素
    vec.erase(vec.begin()); 
    // 此时 it 已经失效,不能再使用
    // std::cout << *it << std::endl; // 错误:使用失效的迭代器
    return 0;
}

5.3. 调整容器大小引起的迭代器失效

调用vectorresizereserve等方法改变容器大小时,若触发了内存重新分配,所有迭代器都会失效。

cpp 复制代码
#include <iostream>
#include <vector>

int main() {
    std::vector<int> vec = {1, 2, 3};
    auto it = vec.begin();
    // 调整容器大小可能导致内存重新分配
    vec.resize(10); 
    // 此时 it 已经失效,不能再使用
    // std::cout << *it << std::endl; // 错误:使用失效的迭代器
    return 0;
}

5.4. 避免迭代器失效的方法

1. 插入元素时

插入元素后,使用插入操作返回的迭代器来更新原有的迭代器。

cpp 复制代码
#include <iostream>
#include <vector>

int main() {
    std::vector<int> vec = {1, 2, 3};
    auto it = vec.begin();
    // 插入元素并更新迭代器
    it = vec.insert(it, 0); 
    std::cout << *it << std::endl; // 正确:使用更新后的迭代器
    return 0;
}
2. 删除元素时

删除元素后,使用删除操作返回的迭代器来更新原有的迭代器。

cpp 复制代码
#include <iostream>
#include <vector>

int main() {
    std::vector<int> vec = {1, 2, 3};
    auto it = vec.begin() + 1;
    // 删除元素并更新迭代器
    it = vec.erase(vec.begin()); 
    std::cout << *it << std::endl; // 正确:使用更新后的迭代器
    return 0;
}
3. 调整容器大小时

在调用resizereserve等方法后,若发生了内存重新分配,要重新获取迭代器。

cpp 复制代码
#include <iostream>
#include <vector>

int main() {
    std::vector<int> vec = {1, 2, 3};
    auto it = vec.begin();
    vec.resize(10);
    // 重新获取迭代器
    it = vec.begin(); 
    std::cout << *it << std::endl; // 正确:使用更新后的迭代器
    return 0;
}

6. 小知识点补充

1,memmovememcpystrcpy

三者功能差不多,strcpy针对字符,memcpy直接复制字节,memmove也复制字节,但是可以解决内存重叠问题。在无内存重叠的时候memcpy性能更好

2,当我们在没有实例化的类模板里面取东西,如:vector<T> a ,此时编译器无法判断a是类型还是变量。这时候,如果是类型,需要在前面加上typename,变成:typename vector<T> a b(这样就可以用类型a定义b

3,如果已经写了构造函数,还是想让编译器生成默认构造:vector() = default

4,传参的时候后面跟u表示unsigned int,可以避免函数重构,调用时的歧义。如:vector(10u,1)


🌈我的分享也就到此结束啦🌈

要是我的分享也能对你的学习起到帮助,那简直是太酷啦!

若有不足,还请大家多多指正,我们一起学习交流!

📢公主,王子:点赞👍→收藏⭐→关注🔍

感谢大家的观看和支持!祝大家都能得偿所愿,天天开心!!!

相关推荐
The Future is mine25 分钟前
Python计算经纬度两点之间距离
开发语言·python
Enti7c25 分钟前
HTML5和CSS3的一些特性
开发语言·css3
爱吃巧克力的程序媛33 分钟前
在 Qt 创建项目时,Qt Quick Application (Compat) 和 Qt Quick Application
开发语言·qt
云 无 心 以 出 岫1 小时前
贪心算法QwQ
数据结构·c++·算法·贪心算法
独好紫罗兰1 小时前
洛谷题单3-P5719 【深基4.例3】分类平均-python-流程图重构
开发语言·python·算法
换一颗红豆1 小时前
【C++ 多态】—— 礼器九鼎,釉下乾坤,多态中的 “风水寻龙诀“
c++
篝火悟者1 小时前
自学-C语言-基础-数组、函数、指针、结构体和共同体、文件
c语言·开发语言
随便昵称2 小时前
蓝桥杯专项复习——前缀和和差分
c++·算法·前缀和·蓝桥杯
commonbelive2 小时前
团体程序设计天梯赛——L1-100 四项全能
c++
genispan2 小时前
QT/C++ 多线程并发下载实践
开发语言·c++·qt