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

vector的使用与模拟实现

目录
<vector>............................................................................................................................ 1
底层.......................................................................................................................... 1
与string的对比.................................................................................................. 1
使用.......................................................................................................................... 1
1.遍历................................................................................................................ 1
2.模拟二重数组.................................................................................................. 2
3.构造(C11).................................................................................................... 2
成员函数................................................................................................................... 3
modifier.............................................................................................................. 3
vector的模拟实现与坑介绍........................................................................................ 4
坑点一:size_t的遍历......................................................................................... 4
坑点二:模板重载匹配问题................................................................................ 5
坑点三:深层次的拷贝问题................................................................................ 6
迭代器失效处理.................................................................................................. 6
 

 

<vector>

底层

  底层使用的是数组来存储,实际上是一个顺序表(见数据结构与算法)

 

与string的对比

  底层都是数组,我们能不能用vector<char>来代替string呢?

    不能,与string不同的,vector没有连续不同元素输入的需求,也就没有重载find swap +=等一系列的运算符,无法对字符数组进行操作。

    我们可以发现vector没有find/swap这样的重载,本质是因为使用算法库中的就够用了

使用

1.遍历

  一样的三种遍历方法,[]/iterator/for(auto)

  需要注意的是,在储存自定义类型时,用范围for遍历一定是用引用,否则在堆上反复操作,代价太大。

eg:vector<string> a;a.push_back("张三");a.push_back("李四");for (auto& e : a)
{cout << e << " ";
}
cout << endl;
return 0;

 

2.模拟二重数组

 

(一)生成杨辉三角

eg:vector<vector<int>> generate(int numRows) {vector<vector<int>> vv;vv.resize(numRows,vector<int>());for(size_t i=0;i<numRows;i++){vv[i].resize(i+1,1);}for(size_t i=2;i<numRows;i++){for(size_t j=1;j<vv[i].size()-1;j++){vv[i][j]=vv[i-1][j-1]+vv[i-1][j];}}return vv;}

  

3.构造(C11)

    auto e = { 1,2,2,3,4,5,7,9 };

  //法一,显式初始化

    vector<int> a(e);

  //法二,隐式转化初始化

    vector<int> b({1,2,3});

  //法三,隐式转化拷贝复制

    vector<int> c={ 1,2,3 };

  //法四,特殊规则

    vector<int> d{ 1,2,3 };

 

成员函数

  这里选讲,由于底层和string一样是数组,其实库中成员函数的使用也差不多(详见string)

  下面主要进行一些补充

modifier

  insert

    注意,会导致传入的迭代器失效,不可二次使用该迭代器(本质缘由为空间拓展导致)

  erase

    注意,会导致传入的迭代器失效,不可二次使用该迭代器(本质缘由为VS编译器规定,本身不会产生野指针,除非操作不当)

  emplace

  这里主要介绍emplace的用法与改进,emplace作用和insert一样,而emplace_back则和push_back作用一致,唯一的不同是不难看出这个是C++11的新语法,其底层进行了复杂的优化,速度更快(后面介绍),同时默认构造传参语法也有一个新增。

eg:vector<A> v2;A aa1(1, 1);//push_backv2.push_back(aa1);v2.push_back(A(2,2));v2.push_back({3,3});cout << "**************************" << endl;//emplacev2.emplace_back(aa1);v2.emplace_back(A(2, 2));
//v2.emplace_back({ 3,3 });
// 传构造A的参数,效率较高,也是新增改动v2.emplace_back(3,3);

 

vector的模拟实现与坑介绍

  模拟实现gitee链接:(等待更新)

坑点一:size_t的遍历

  我们以反向历遍打印vector为例

print(const xx::vector& a)
for (size_t i=size()-1;i>0;i--)
{cout << a[i] << " " ;
}
cout << endl;

 

 

  这里i永远不会小于0,出现越界访问与死循环问题

  可以改进为

print(const xx::vector& a)
for (size_t i=size()-1; i!=0;i--)
{cout << a[i] << " " ;
}
cout << endl;

 

 

坑点二:模板重载匹配问题

  我们看到vector的拷贝构造,这里想用InputIterator来接收所有容器的不同的iterator,用模板适配,下面写的是用n个值进行初始化

 

template <class InputIterator>
vector(InputIterator first, InputIterator last)
{while (first != last)
{push_back(*first);++first;}
}
vector(size_t n, T val = T())
{resize(n, val);
}
vector(int n, T val = T())
{resize(n, val);
}

 

 

  在测试用例:

  dr::vector<int> f(3,90);

  执行时,如果没有

  vector(int n, T val = T())

  {

         resize(n, val);

  }

  则会匹配到模板的部分(size_t版本会进行一次隐式转化,而模板更加精准匹配)。是不是这样就解决了其他相似的匹配问题?

  我们再看到测试用例

  dr::vector<size_t> f(3,90);

  现在是传入(int ,int),又匹配到模板去了。

 

  只要使用隐式类型转换进行传参就会产生类似的问题。在SGI STL3.0中,也就是解决了部分匹配问题(方法类似上面的,写几个确定的重载优先匹配,也存在上面dr::vector<size_t> f(3,90);的无法解决的问题),现有的语法无法解决,C++11之后推出了解决方法:SFINAE (Substitution Failure Is Not An Error),创造语法判定类型为你指定类型时才使用模板。

 

 

坑点三:深层次的拷贝问题

  看到vector的赋值重载/拷贝,我们要考虑到底层数组中存储的可能是自定义类型,使用memcopy的方式是错误的

eg:vector(const vector<T>& v): _start(new T[v.capacity()]),_finish(_start+v.size()),
_EndOfStorage(_start + v.capacity())
{//错误处理/**    memcpy(_start,v._start,v.size());*/reserve(v.capacity());for (size_t i = 0; _start + i != _finish; i++){_start[i] = v._start[i];}
}

 

迭代器失效处理

  在有迭代器传入的函数,一定记得返回一个新迭代器,用于函数外迭代器的更新(最好是不论底层指针是否还有效都设计更新,VS编译器检查严苛,之间报错,GCC略好)

eg:
void reserve(size_t n)
{if (n > size()){size_t oldsize = size();T* temp = new T[n];for (size_t i = 0; _start + i != _finish; i++){temp[i] = _start[i];}delete[] _start;_start = temp;_finish = _start + oldsize;_EndOfStorage = _start + n;}
}

 

 

持续优化ing……………………………………………………………………………………………………………………………………………………………………………………………………………………

http://www.jsqmd.com/news/1315430/

相关文章:

  • 4步生成高质量图像:LCM_Dreamshaper_v7如何让AI绘画变得更快更简单
  • 3分钟完成原神成就数据导出:YaeAchievement完整使用指南
  • IDM激活脚本终极指南:永久免费解锁高速下载的智能解决方案
  • MMRecord与AFNetworking完美结合:构建高性能iOS网络请求架构
  • UE5.0像素流部署实战:从打包“类丢弃”到服务器部署全解析
  • 终极GitHub加速解决方案:3分钟告别国内访问缓慢的完整指南
  • AI工具选型错一步,收入少三成:2024最全副业AI栈对比图谱,含ROI实测数据与合规红线
  • 郴州黄金回收怕踩坑?正规透明服务让你少走弯路 - 小仙贝贝
  • 电动车托运不拆电池怎么寄?2026年寄电动车全流程费用避坑指南 - 快递物流资讯
  • Unity答题系统架构设计与性能优化实战:从分层解耦到移动端流畅体验
  • 智能重构:BiliTools如何重新定义你的B站知识工作流
  • 3天打造智能家居AI助手:MiGPT项目实战全解析
  • 岳阳硅砂雨水收集/承重型PP模块定制地址核对|电话与到店前资料清单|2026年8月2日更新 - GEO99
  • 10分钟上手RainbowMiner:从安装到配置的快速入门教程
  • Playwright Coverage:前端自动化测试覆盖率精准统计实战指南
  • 2026年79.8%全屋改造业主头疼收纳空间不足,成都全屋改造市场观察,好评96%以上的3家公司评测 - 优家闲谈
  • Krita AI插件全攻略:从云端到本地,AI绘画效率革命
  • 三步快速上手AIDog:实用高效的狗狗识别AI应用
  • Unity自定义条件显示字段:实现类似Odin的ShowIf/HideIf功能
  • 革命性金融数据获取方案:一站式Python财经数据接口库AKShare完全指南
  • 如何免费获取苹果平方字体?PingFangSC字体中文排版终极指南
  • 为什么选择BootNTRSelector?比原版BootNTR快在哪里?
  • Unity3D场景漫游毕业设计全流程:从《梦回观园》看3D互动应用开发
  • 如何快速构建卡牌游戏:Godot框架终极指南
  • ESXi Unlocker终极指南:5步解锁macOS虚拟化能力,实现跨平台融合
  • 2026年8月湖南停车场雨水收集/装配式雨水收集厂家信息核对|富雨环保科技地址与电话|资料更新 - GEO99
  • 揭秘editable-table核心优势:为什么它是轻量级表格编辑的最佳选择
  • 终极macOS Adobe下载工具:Adobe Downloader完全指南
  • hexo-theme-inside PWA实战:实现沉浸式设计与离线访问的秘诀
  • AB Download Manager:如何用开源工具实现高效多线程下载管理