当前位置: 首页 > news >正文

vector的基本使用 + 手搓成员变量 size capacity begin end operator[] reserve扩容 拷贝构造 赋值析构

vector

文章目录

  • vector
    • 0.是什么
    • 头文件:\<vector>
  • 1.构造
  • 2.遍历
  • 3.reserve
  • 4.resize
  • 5.插入
    • 5.1push_back
    • 5.2insert
  • 手搓
    • private:
    • size,capacity,empty
    • 实现迭代器和operator[ ]
    • reserve扩容
      • ❌错误示例:
      • 修改方式1:
      • 修改方式2:
    • push_back

0.是什么

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

——>是一个类模板




头文件:<vector>






1.构造

vector<int>v1;//创建一个空vectorvector<int>v2(10,1);//创建一个vector,里面有10个1vector<int>v3(++v2.begin(),--v2.end());//按迭代器创建一个vector,里面有8个1//迭代器换成数组下标intarr[]={1,2,3,4,5};vector<int>v4(arr,arr+5);vector<int>v{2,3,4,6,1,7};//后面再说
  • vector<int>类模板实例化
  • vector<int> v1;用这个 类定义了一个对象(变量)v1,并调用默认构造函数。
  • vector<int> v2(10, 1);用这个 类定义了一个对象(变量)v1,并调用 构造函数

关于类模板的知识在这里

为什么直接用数组下标也能构造?

  1. 指针满足迭代器的所有要求,指针可以直接用来充当迭代器

  2. vector有(范围)构造函数:

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

    是一个模板函数,它不关心 传进来的 类型,只要 满足 " 迭代器" 就行。

    ——>通过这个模版生成函数来构造

    模板函数自动类型推导的知识在这里:【纯干货】C++ 模板核心知识点 函数模板 / 类模板语法 + 面试高频坑(类型推)导 / 实例化 / 分离编译)






2.遍历

  1. 下标(实际上是 重载operator[ ])
  2. 通过迭代器
  3. 范围for
vector<int>v{2,3,4,6,1,7};for(inti=0;i<v.size();i++)cout<<v[i]<<",";vector<int>::iterator it=v.begin();while(it!=v.end()){cout<<*it<<endl;++it;}for(autoe:v)cout<<e<<" ";

有关类和对象的知识,在这里:

【万字干货】C++类和对象从入门到精通:内存划分/访问限定符/this指针/默认成员函数/const用法/类型转换全拆解,附C++实现顺序表、链表、栈——吃透大厂面试高频考点-CSDN博客

AI问了好久!终于搞懂 C++ 命名空间 / 类 / 对象,90% 初学者都踩过的 getline 天坑全解-CSDN博客

类 = 类型,对象 = 用这个类型创建出来的变量

概念对应现实事物说明
头文件(#include <string>电脑上的文件夹按功能分类存放代码的容器
命名空间(std文件夹里的大箱子防止名字冲突的隔离层
类(std::string箱子里的小盒子自定义的类型,描述一类事物的共同属性和行为
对象(std::string s;用小盒子装的具体物品用类创建出来的变量,是实际存在的实体
函数(std::getline箱子里的独立工具完成特定功能的代码块
全局对象(std::cin箱子里已经装好的现成工具标准库提前创建好、可以直接使用的对象
  • C++ 标准库所有的东西都在std这个命名空间里
  • 同名的命名空间会自动合并
  • 不同的标准库头文件,只是把std这个大命名空间分成了不同的小块

3.reserve

文档中说不会缩容

Ifnis greater than the current vector capacity, the function causes the container to reallocate its storage increasing its capacity ton(or greater).

In all other cases, the function call does not cause a reallocation and the vector capacity is not affected.

vector<int>v{2,3,4,6,1,7};cout<<"size:"<<v.size()<<endl<<"capacity:"<<v.capacity()<<endl;v.reserve(10);cout<<"size:"<<v.size()<<endl<<"capacity:"<<v.capacity()<<endl;v.reserve(6);cout<<"size:"<<v.size()<<endl<<"capacity:"<<v.capacity()<<endl;size:6capacity:6size:6capacity:10size:6capacity:10





4.resize

  • n<size,删除数据
  • n>size,插入数据(插入传的第二个参数,没传就用value_type()),空间(capacity)不够就扩容

value_type是容器的元素类型别名value_type()就是该元素类型的默认构造函数

比如:

  • vector<int>value_type()就是int()→ 0
  • vector<string>value_type()就是string()→ 空字符串

resize 扩容时,如果你没指定填充值,就用这个默认值填充新元素。

vector<int>v{2,3,4,6,1,7};for(autoe:v)cout<<e<<" ";cout<<endl;cout<<"size:"<<v.size()<<endl<<"capacity:"<<v.capacity()<<endl;v.resize(10);for(autoe:v)cout<<e<<" ";cout<<endl;cout<<"size:"<<v.size()<<endl<<"capacity:"<<v.capacity()<<endl;v.resize(2);for(autoe:v)cout<<e<<" ";cout<<endl;cout<<"size:"<<v.size()<<endl<<"capacity:"<<v.capacity()<<endl;234617size:6capacity:62346170000size:10capacity:1023size:2capacity:10





5.插入

5.1push_back

vector<int>v{2,3,4,6,1,7};v.push_back(88);

5.2insert

‼️注意点:

insert 后迭代器可能失效insert可能导致扩容,所有迭代器、引用、指针失效。)

  1. 头插/中间插入(通过迭代器)
  2. 插入多个数据
    1. 通过迭代器
    2. 连续插入相同数据
vector<int>v1{2,3,4,6,1,7};v1.insert(v1.begin()+3,5);//打印vector<int>v2{1,1,1,1,1,1};v1.insert(v1.begin(),v2.begin(),v2.begin()+4);//打印v1.insert(v1.begin(),2,0);//打印2345617111123456170011112345617








手搓

private:

// vector.hnamespacelcj{template<classT>classvector{public:// ...private:iterator _start=nullptr;// 指向数组的起始位置iterator _finish=nullptr;// 指向最后一个有效数据的下一个位置iterator _end_of_storage=nullptr;// 指向整个已分配空间的末尾};}





size,capacity,empty

// 返回有效元素个数size_tsize()const{return_finish-_start;}// 返回总容量size_tcapacity()const{return_end_of_storage-_start;}// 判断是否为空boolempty(){return_start==_finish;}





实现迭代器和operator[ ]

// vector的迭代器本质就是原生指针!typedefT*iterator;typedefconstT*const_iterator;// 普通迭代器(可以修改元素)iteratorbegin(){return_start;}iteratorend(){return_finish;}// const迭代器(只能读不能改)const_iteratorbegin()const{return_start;}const_iteratorend()const{return_finish;}// 普通版本,可以修改元素T&operator[](size_t i){assert(i<size());// 下标越界直接崩溃,比原生数组安全return_start[i];}// const版本,只能读不能改constT&operator[](size_t i)const{assert(i<size());return_start[i];}





reserve扩容

此处使用的memcpy是逐字节拷贝,对于std::stringvector等类类型,会导致浅拷贝,后面会细说

❌错误示例:

  • size()是个函数,这时候会计算:_finish - _start;,可是这时候:_start = tmp;start已经不是原来的start了

    ——>计算的size()是错的

voidreserve(size_t n){if(n>capacity()){T*tmp=newT[n];memcpy(tmp,_start,sizeof(T)*size());delete[]_start;_start=tmp;_finish=_start+size();_end_of_storage=_start+n;}}



修改方式1:

  • 先改_finish:_finish = tmp + size();,这时候size()还是用的原来的_finish
voidreserve(size_t n){if(n>capacity()){T*tmp=newT[n];memcpy(tmp,_start,sizeof(T)*size());delete[]_start;_finish=tmp+size();_start=tmp;_end_of_storage=_start+n;}}



修改方式2:

  • 提前记录下原来的有效元素个数
// vector.hvoidreserve(size_t n){if(n>capacity()){size_t old_size=size();// 1. 先记录下原来的有效元素个数T*tmp=newT[n];// 2. 开新空间memcpy(tmp,_start,size()*sizeof(T));// 3. 拷贝数据delete[]_start;// 4. 释放旧空间_start=tmp;// 5. 更新三个指针_finish=tmp+old_size;/////////////////////////////////////////////////////////////////_end_of_storage=tmp+n;}}





push_back

voidpush_back(constT&x){// 检查是否需要扩容if(_finish==_end_of_storage){reserve(capacity()==0?4:capacity()*2);}*_finish=x;// 在当前finish位置存放数据++_finish;// 移动 finish 指针}
http://www.zskr.cn/news/1423882.html

相关文章:

  • 2026年AI论文网站盘点:12款神器助你高效完成开题写作、改稿和答辩
  • 暗黑破坏神2终极优化指南:用d2dx让你的经典游戏焕然一新
  • 如何快速通过手机号找回遗忘的QQ号:终极完整指南
  • 激光武器反无人机作战效能评估综述
  • 100、CAN FD的软件栈与协议栈设计:驱动、配置与调试技巧
  • Raspberry Pi Pico WH MicroPython入门:从环境搭建到LED闪烁实战
  • DEAP脑电数据驱动的情绪识别实践包:微分熵三维特征+轻量CNN模型(含论文、代码与完整运行流程)
  • 百考通AI----多元分析,论文降重与降AIGC双重保障
  • GEO vs SEO:一场关于“被谁看见“的战争
  • 景区运营新利器——把一名员工升级为“一人部门”
  • 13604黄大年茶思屋榜文第136期:第四期 强干扰下,收发分离架构无源物联接收机的干扰抑制能力提升 标准化解题框架
  • 行为互联网(IoB)实战指南:从数据闭环到商业价值落地
  • 快手这份财报,最该看的不是短视频,是可灵AI开始赚钱了
  • ITO靶材微观结构均匀性如何影响溅射良率?国内企业排名
  • 2026必应推广全维度解析 杭州专业服务商实操指南
  • NVIDIA Profile Inspector终极指南:解锁显卡隐藏性能的专业工具
  • d2s-editor:暗黑破坏神2存档编辑神器,打造你的专属游戏体验
  • SolidWorks PDM二次开发避坑:文件夹删除和刷新操作的3个常见错误与正确写法
  • 篮球赛事运营系统四层源码包:uniapp小程序+Vue后台+Node.js接口+MySQL数据库
  • 如何快速提升Windows性能:终极免费内存优化解决方案
  • 成都钢材生产厂家|一站式供应钢材、全品类仓储贸易中心 - 四川盛世钢联营销中心
  • 从法拉第定律到单极电动机:电磁原理的直观实践与制作指南
  • 为什么你复制别人的 STM32 工程,到了自己电脑就报错一堆?
  • Win11任务栏图标合并太烦人?试试这个“偷梁换柱”法:手动替换explorer.exe文件实战记录
  • Sciverse Paper Reader 指南:科学论文如何做结构化阅读
  • 基于Arduino与红外手势传感器的智能交互系统设计与实现
  • ROS避障机器人实战:用C++和Python分别实现激光雷达避障(附完整代码与Gazebo仿真)
  • 通话Agent技术实现指南-从电话机器人到智能对话系统
  • Terraform 模块中的 count:批量创建、条件部署与版本陷阱全解析
  • 运维人的核心竞争力:不是技术,是思维方式