当前位置: 首页 > 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.jsqmd.com/news/912568/

相关文章:

  • 百考通AI:让毕业论文写作告别焦虑,对于不同学历层次的学生,多元分析
  • 什么是 Vibe Coding?为什么企业不能只停留在快速原型 | 星云PLUS
  • DIY微型涡轮发电机:用酸奶瓶盖验证电磁感应与能量转换
  • 从“建起来“到“用起来“:高校大数据实验室建设的系统性解法
  • 2026甄选:成都/自贡/攀枝花/泸州二手冷库冻库回收服务公司评估与选择 - 品牌企业推荐师(官方)
  • 暗黑破坏神2终极优化指南:用d2dx让你的经典游戏焕然一新
  • OPC中国是什么?技术方法论与实操流程
  • android14 rk628H hdmi转lvds概率性黑屏问题
  • 如何快速通过手机号找回遗忘的QQ号:终极完整指南
  • 中电金信:不说概念,看投入:银行数智化到底在卷什么
  • Windows 10资源管理器CPU占用100%?别急着重装,用Process Explorer揪出真凶Network List Service
  • 激光武器反无人机作战效能评估综述
  • AI正在悄悄帮住宿老板“干掉”OTA依赖
  • 100、CAN FD的软件栈与协议栈设计:驱动、配置与调试技巧
  • 基于Arduino的智能颗粒粉末自动分配器DIY全攻略
  • 不仅是 Copilot:AI Agent Harness Engineering 如何从辅助角色进化为业务执行主体?
  • Raspberry Pi Pico WH MicroPython入门:从环境搭建到LED闪烁实战
  • DEAP脑电数据驱动的情绪识别实践包:微分熵三维特征+轻量CNN模型(含论文、代码与完整运行流程)
  • AI Agent Harness Engineering 物流行业应用:包裹分拣、路径优化与配送跟踪自动化
  • 新手避坑指南:在Ubuntu 20.04上从零配置ROS Melodic激光雷达仿真环境(含RViz可视化)
  • 百考通AI----多元分析,论文降重与降AIGC双重保障
  • AI资讯简报高效管理指南:从信息过载到精准获取
  • 一人做TikTok跨境电商?AI智能体帮你搞定翻译、剪辑、客服
  • 2026夏护腰带选购指南:谁更靠谱?
  • AI自动化在医疗领域的应用有哪些?
  • 2026年北京精密机械加工实力厂家选择:精密零件/钣金/冲压模具/CNC数控/非标机械加工企业深度解析 - 品牌企业推荐师(官方)
  • 运维避坑指南:在银河麒麟V10 SP1用tcpdump抓包,这3个权限和路径问题你遇到了吗?
  • 3分钟定位Windows热键冲突:Hotkey Detective一键诊断解决方案
  • GEO vs SEO:一场关于“被谁看见“的战争
  • 景区运营新利器——把一名员工升级为“一人部门”