vector文章目录vector0.是什么头文件\vector1.构造2.遍历3.reserve4.resize5.插入5.1push_back5.2insert手搓private:sizecapacityempty实现迭代器和operator[ ]reserve扩容❌错误示例修改方式1修改方式2push_back0.是什么template class T, class Alloc allocatorT class vector; // generic template——是一个类模板头文件vector1.构造vectorintv1;//创建一个空vectorvectorintv2(10,1);//创建一个vector里面有10个1vectorintv3(v2.begin(),--v2.end());//按迭代器创建一个vector里面有8个1//迭代器换成数组下标intarr[]{1,2,3,4,5};vectorintv4(arr,arr5);vectorintv{2,3,4,6,1,7};//后面再说vectorint类模板实例化vectorint v1;用这个 类定义了一个对象变量v1并调用默认构造函数。vectorint v2(10, 1);用这个 类定义了一个对象变量v1并调用 构造函数关于类模板的知识在这里为什么直接用数组下标也能构造指针满足迭代器的所有要求指针可以直接用来充当迭代器vector有范围构造函数template class InputIteratorvector(InputIterator first, InputIterator last);是一个模板函数它不关心 传进来的 类型只要 满足 迭代器 就行。——通过这个模版生成函数来构造模板函数自动类型推导的知识在这里【纯干货】C 模板核心知识点 函数模板 / 类模板语法 面试高频坑类型推导 / 实例化 / 分离编译2.遍历下标实际上是 重载operator[ ]通过迭代器范围forvectorintv{2,3,4,6,1,7};for(inti0;iv.size();i)coutv[i],;vectorint::iterator itv.begin();while(it!v.end()){cout*itendl;it;}for(autoe:v)coute ;有关类和对象的知识在这里【万字干货】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.vectorintv{2,3,4,6,1,7};coutsize:v.size()endlcapacity:v.capacity()endl;v.reserve(10);coutsize:v.size()endlcapacity:v.capacity()endl;v.reserve(6);coutsize:v.size()endlcapacity:v.capacity()endl;size:6capacity:6size:6capacity:10size:6capacity:104.resizensize删除数据nsize插入数据插入传的第二个参数没传就用value_type()空间capacity不够就扩容value_type是容器的元素类型别名value_type()就是该元素类型的默认构造函数。比如vectorint的value_type()就是int()→ 0vectorstring的value_type()就是string()→ 空字符串resize 扩容时如果你没指定填充值就用这个默认值填充新元素。vectorintv{2,3,4,6,1,7};for(autoe:v)coute ;coutendl;coutsize:v.size()endlcapacity:v.capacity()endl;v.resize(10);for(autoe:v)coute ;coutendl;coutsize:v.size()endlcapacity:v.capacity()endl;v.resize(2);for(autoe:v)coute ;coutendl;coutsize:v.size()endlcapacity:v.capacity()endl;234617size:6capacity:62346170000size:10capacity:1023size:2capacity:105.插入5.1push_backvectorintv{2,3,4,6,1,7};v.push_back(88);5.2insert‼️注意点insert 后迭代器可能失效insert可能导致扩容所有迭代器、引用、指针失效。头插/中间插入通过迭代器插入多个数据通过迭代器连续插入相同数据vectorintv1{2,3,4,6,1,7};v1.insert(v1.begin()3,5);//打印vectorintv2{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{templateclassTclassvector{public:// ...private:iterator _startnullptr;// 指向数组的起始位置iterator _finishnullptr;// 指向最后一个有效数据的下一个位置iterator _end_of_storagenullptr;// 指向整个已分配空间的末尾};}sizecapacityempty// 返回有效元素个数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;}// 普通版本可以修改元素Toperator[](size_t i){assert(isize());// 下标越界直接崩溃比原生数组安全return_start[i];}// const版本只能读不能改constToperator[](size_t i)const{assert(isize());return_start[i];}reserve扩容此处使用的memcpy是逐字节拷贝对于std::string、vector等类类型会导致浅拷贝后面会细说❌错误示例size是个函数这时候会计算_finish - _start;可是这时候_start tmp;start已经不是原来的start了——计算的size是错的voidreserve(size_t n){if(ncapacity()){T*tmpnewT[n];memcpy(tmp,_start,sizeof(T)*size());delete[]_start;_starttmp;_finish_startsize();_end_of_storage_startn;}}修改方式1先改_finish:_finish tmp size();这时候size()还是用的原来的_finishvoidreserve(size_t n){if(ncapacity()){T*tmpnewT[n];memcpy(tmp,_start,sizeof(T)*size());delete[]_start;_finishtmpsize();_starttmp;_end_of_storage_startn;}}修改方式2提前记录下原来的有效元素个数// vector.hvoidreserve(size_t n){if(ncapacity()){size_t old_sizesize();// 1. 先记录下原来的有效元素个数T*tmpnewT[n];// 2. 开新空间memcpy(tmp,_start,size()*sizeof(T));// 3. 拷贝数据delete[]_start;// 4. 释放旧空间_starttmp;// 5. 更新三个指针_finishtmpold_size;/////////////////////////////////////////////////////////////////_end_of_storagetmpn;}}push_backvoidpush_back(constTx){// 检查是否需要扩容if(_finish_end_of_storage){reserve(capacity()0?4:capacity()*2);}*_finishx;// 在当前finish位置存放数据_finish;// 移动 finish 指针}