vector的使用和模拟

发布时间:2026/10/28 9:28:52

vector的使用和模拟 目录vector的基本使用构造函数拷贝构造迭代器容器元素访问修改emplace_back和push_back区别结构化绑定迭代器失效vector的模拟迭代器容器元素访问元素修改构造、赋值和析构:总代码综合总结vector的基本使用构造函数templateclass Constain void Print(const Constain con) { for (auto e : con) { cout e ; } cout endl; } int main() { //以下三种都可以一般会忽略括号直接用花括号 //vectorint v1({ 1,2,3,4,5 }); vectorint v1{ 1,2,3,4,5 }; //vectorint v1 { 1,2,3,4,5 }; Print(v1); vectorint v2(20, 100); Print(v2); vectorint v3(v1.begin() 2, v1.end()); Print(v3); return 0; }运行结果以上是我觉得较为有用的初始化构造函数c98需要其他构造可以直接查阅文档vector::vector - C Reference拷贝构造vectorint v4 v1;//这里继承了上面的代码{12345} Print(v4);迭代器这里迭代器就不一一写了这里可以理解成像指针一样的东西进行遍历使用就好了如//可修改 void test02() { vectorint v1 {1,2,3,4,5}; vectorint::iterator it1 v1.begin(); while (it1 ! v1.end()) { cout *it1 ; it1; } } //只读 void test03() { vectorint v1 {1,2,3,4,5}; vectorint::const_iterator it1 v1.cbegin(); while (it1 ! v1.cend()) { cout *it1 ; it1; } } //反向迭代器 void test04() { vectorint v1 {1,2,3,4,5}; vectorint::reverse_iterator it1 v1.rbegin(); while (it1 ! v1.rend()) { cout *it1 ; it1; } }运行结果容器void test05() { vectorstring v1 { hellow,world,!!!!! }; cout 大小: v1.size() endl; cout 扩容前: v1.capacity() endl; cout v1.max_size() endl;//没实际意义扩容阔不了这么大 v1.resize(5, bear); Print(v1); cout resize扩容后: v1.capacity() endl; cout 判空: v1.empty() endl; v1.reserve(10); cout reserve扩容后: v1.capacity() endl; v1.shrink_to_fit(); cout shrink_to_fit缩容后: v1.capacity() endl; }元素访问void test06() { vectorstring v1 { hellow,world,!!!!! }; cout operator[]: v1[1] endl; cout at: v1.at(1) endl; cout front: v1.front() endl; cout back: v1.back() endl; cout data: v1.data() endl;//返回起始元素地址 }运行结果修改void test07() { vectorint v1{1,2,3,4,5}; v1.assign(20, 100);//替代原来的vector Print(v1); vectorint v2; v2.push_back(1); v2.push_back(2); v2.push_back(3); v2.push_back(4); v2.push_back(5); Print(v2); v2.pop_back(); cout pop_back后:; Print(v2); v2.insert(v2.begin()2, 100); cout insert插入后:; Print(v2); v2.erase(v2.begin() 1); cout erase删除后:; Print(v2); vectorint v3; v3.swap(v2); cout 交换后的v2:; Print(v2); cout 交换后的v3:; Print(v3); v3.clear(); cout clear的v3:; Print(v3); }emplace_back和push_back区别emplace_back和push_back构造一个临时对象然后将其拷贝或移动到容器中在初始化时在特殊场景下emplace_back效率会更高直接在容器内存中构造对象避免创建临时对象push_back和emplace_back在扩容过程中都会调用拷贝构造。void test08() { struct A { A(int a,int b,int c) :_a(a) ,_b(b) ,_c(c) { cout A() endl; } A(const A aa) { cout A(const A aa) endl; _a aa._a; _b aa._b; _c aa._c; } int _a 1; int _b 2; int _c 3; }; vectorint v1; //内置类型效率差不多 v1.push_back(1); v1.emplace_back(1); for (auto e : v1) { cout e ; } cout endl; cout endl; vectorA v2; //v2.reserve(10); //完整对象 A aa1(4, 5, 6); cout ******************************** endl; cout push_back完整实例化对象:endl; v2.push_back(aa1); v2.push_back(A(7,8,9));//匿名对象 cout push_back:传递构造参数不是完整实例化对象 endl; //需要调用构造再调用拷贝构造 v2.push_back({ 1,2,3 }); cout emplace_back完整实例化对象:endl;; //这里拷贝2次是因为第一个拷贝是因为扩容拷贝然后第二次是需要拷贝到vector中 v2.emplace_back(aa1); v2.emplace_back(A(7, 8, 9)); cout emplace_back:传递构造参数不是完整实例化对象 endl; //避免临时对象的产生直接调用构造效率较高 v2.emplace_back( 1,2,3 ); cout endl; cout endl; }这里很明显在传递构造参数时就会使得拷贝构造变少甚至不拷贝但是在其他方面如已初始化的反而会拷贝更多拷贝结构化绑定结构化绑定用于类型是自定义类型的类就是一个自定义类型有多个成员访问就好用和范围for一样只不过范围for不好写多个成员访问这里结构化绑定就是可以直接访问。可能发生拷贝构造可以用引用消除这个拷贝构造void test09() { struct A { A(int a, int b, int c) :_a(a) , _b(b) , _c(c) { cout A() endl; } A(const A aa) { cout A(const A aa) endl; _a aa._a; _b aa._b; _c aa._c; } int _a 1; int _b 2; int _c 3; }; //c17标准 //auto [x, y, z] A(2, 3, 4); A aa1(2, 3, 4); vectorA v4; v4.push_back(aa1); for (auto [x, y, z] : v4) { cout x y z endl; } }struct test001 { int a 12; int b 32; }; struct test002 { test001 n test001(); }; //auto [x, y] test002();//erro auto [x] test002(); auto [y,z] x; cout y : z endl;注意这里结构化绑定不能直接访问类成员中成员变量需要一步一步分解。迭代器失效vector迭代器失效指的是不能继续使用迭代器扩容会改变迭代器指针是位置而对应的pos位置指针不会给你改变会导致野指针对于迭代器失效就可以使用返回值来保留当前位置更新就能继续使用vector的模拟迭代器namespace bear { templateclass T class vector { public: // Vector的迭代器是一个原生指针 typedef T* iterator; typedef const T* const_iterator; iterator begin() { return _start; } iterator end() { return _finish; } const_iterator cbegin()const { return _start; } const_iterator cend() const { return _finish; } private: iterator _start; // 指向数据块的开始 iterator _finish; // 指向有效数据的尾 iterator _endOfStorage; // 指向存储容量的尾 }; }容器//size size_t size() const { return _finish - _start; } //capacity size_t capacity() const { return _endOfStorage - _start; } //扩容 void reserve(size_t n) { if (n capacity()) { T* tmp new T[n]; size_t old_size _finish - _start; if (_start) { //memcpy(tmp, _start,_finish-_start);//只能浅拷贝 for (size_t i 0; i size(); i) { //可以调用需要深拷贝的构造 tmp[i] _start[i]; } delete[] _start; } _start T; _finish _start old_size; _endOfStorage _start n; } } //resize void resize(size_t n, const T value T()) { if (n capacity()) { reserve(n); iterator it1 _start size(); while (it1 ! _start n) { (*it1) value; it1; } _finish _start n; } else { _finish _start n; } }元素访问///////////////access/////////////////////////////// //下标引用 T operator[](size_t pos) { assert(pos _finish); return _start[pos]; } const T operator[](size_t pos)const { assert(pos _finish); return _start[pos]; }元素修改///////////////modify///////////////////////////// void push_back(const T x) { //空间不够 if (_finish _endOfStorage) { reserve(capacity() 0 ? 4 : 2 * capacity()); } *_finish x; _finish; } void pop_back() { --_finish; } void swap(vectorT v) { std::swap(_start, v._start); std::swap(_finish, v._start); std::swap(_endOfStorage, v._endOfStorage); } iterator insert(iterator pos, const T x) { assert(pos _start); assert(pos _finish); if (_finish _endOfStorage) { //保存pos相对位置这里也是为了防止迭代器失效 size_t len pos - _start; reserve(capacity() 0 ? 4 : 2 * capacity()); pos len _start; } iterator it _finish - 1; while (it pos) { *(it 1) *it; --it; } *_finish x; _finish; //防止迭代器失效 return pos; } iterator erase(iterator pos) { assert(pos _start); assert(pos _finish); iterator it pos1; while (it ! _finish) { *(it - 1) *it; it; } --_finish; return pos;//防止迭代器失效 }构造、赋值和析构:// construct and destroy vector() :_start(nullptr) ,_finish(nullptr) ,_endOfStorage(nullptr) { } vector(int n, const T value T()) { resize(n, value); } templateclass InputIterator vector(InputIterator first, InputIterator last) { while (first ! last) { push_back(first); first; } } //拷贝 vector(const vectorT v) { reserve(v.capacity()); for (auto e : v) { push_back(e); } } //赋值 vectorT operator (vectorT v) { swap(v); return *this; } //析构 ~vector() { delete[] _start; _start _finish _endOfStorage nullptr; }总代码综合#pragma once #includeiostream #includeassert.h namespace bear { templateclass T class vector { public: // Vector的迭代器是一个原生指针 typedef T* iterator; typedef const T* const_iterator; iterator begin() { return _start; } iterator end() { return _finish; } const_iterator cbegin()const { return _start; } const_iterator cend() const { return _finish; } // construct and destroy vector() :_start(nullptr) ,_finish(nullptr) ,_endOfStorage(nullptr) { } vector(int n, const T value T()) { resize(n, value); } templateclass InputIterator vector(InputIterator first, InputIterator last) { while (first ! last) { push_back(first); first; } } //拷贝 vector(const vectorT v) { reserve(v.capacity()); for (auto e : v) { push_back(e); } } //赋值 vectorT operator (vectorT v) { swap(v); return *this; } //析构 ~vector() { delete[] _start; _start _finish _endOfStorage nullptr; } //size size_t size() const { return _finish - _start; } //capacity size_t capacity() const { return _endOfStorage - _start; } //扩容 void reserve(size_t n) { if (n capacity()) { T* tmp new T[n]; size_t old_size _finish - _start; if (_start) { //memcpy(tmp, _start,_finish-_start);//只能浅拷贝 for (size_t i 0; i size(); i) { //可以调用需要深拷贝的构造 tmp[i] _start[i]; } delete[] _start; } _start tmp; _finish _start old_size; _endOfStorage _start n; } } //resize void resize(size_t n, const T value T()) { if (n capacity()) { reserve(n); iterator it1 _start size(); while (it1 ! _start n) { (*it1) value; it1; } _finish _start n; } else { _finish _start n; } } ///////////////access/////////////////////////////// //下标引用 T operator[](size_t pos) { assert(pos _finish); return _start[pos]; } const T operator[](size_t pos)const { assert(pos _finish); return _start[pos]; } ///////////////modify///////////////////////////// void push_back(const T x) { //空间不够 if (_finish _endOfStorage) { reserve(capacity() 0 ? 4 : 2 * capacity()); } *_finish x; _finish; } void pop_back() { --_finish; } void swap(vectorT v) { std::swap(_start, v._start); std::swap(_finish, v._start); std::swap(_endOfStorage, v._endOfStorage); } iterator insert(iterator pos, const T x) { assert(pos _start); assert(pos _finish); if (_finish _endOfStorage) { //保存pos相对位置这里也是为了防止迭代器失效 size_t len pos - _start; reserve(capacity() 0 ? 4 : 2 * capacity()); pos len _start; } iterator it _finish - 1; while (it pos) { *(it 1) *it; --it; } *_finish x; _finish; //防止迭代器失效 return pos; } iterator erase(iterator pos) { assert(pos _start); assert(pos _finish); iterator it pos1; while (it ! _finish) { *(it - 1) *it; it; } --_finish; return pos;//防止迭代器失效 } private: iterator _start; // 指向数据块的开始 iterator _finish; // 指向有效数据的尾 iterator _endOfStorage; // 指向存储容量的尾 }; }总结vector这里较为重要的有vector的使用和vector的模拟其中迭代器的失效很重要通过底层实现vector的中发现在任意删和任意插insert,erase中pos指向会发生改变这就导致了迭代器的失效这里解决这个问题就是更新pos位置然后返回pos对应的指针。ps:vector底层实现是靠的指针所以元素起始位置地址和vector类的地址是不一样的vector类保存的地址是私有成员中_ptr的成员地址(vector保存了_ptr内部保存的地址的地址相当于套了一个壳)在这里只是保存了指针变量的地址而不是指针变量指向的地址(_ptr变量内部保存的地址)但是在这个_ptr成员中指向的是数组起始位置。vector 对象 └─ _ptr 一个指针变量它自己有个地址 _ptr ≈ v └─ _ptr 的值 指向堆上数组 v.data()
延伸阅读

更多相关文章

2026/10/28 9:28:52

List迭代器和模拟(迭代器的模拟)

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/28 9:23:49

虚拟世界法律框架:智能合约与数字治理实践

1. 项目背景与核心价值"数字创世纪:在虚拟世界重写人类法典"这个项目名称本身就蕴含着深刻的时代命题。当元宇宙、数字孪生等技术从概念走向落地,我们突然发现:虚拟世界正在形成一套独立于现实社会的运行规则。去年某知名虚拟平台爆…

2026/10/28 10:29:22

从光子计数到场景感知:单光子激光雷达技术发展现状与趋势

从光子计数到场景感知:单光子激光雷达技术发展现状与趋势 摘要:单光子激光雷达以光子级探测灵敏度突破了传统线性激光雷达在作用距离与弱回波条件下的性能边界,正在从实验室走向遥感测绘、智能驾驶与消费电子的规模化应用。当前该领域的技术演进呈现出两条相互交织的主线:…

2026/10/28 10:29:22

SpringBoot 结合Mybatis

新建项目后创建目录之后编写mapper类对应代码主方法的类中添加注释编写新增的方法确认返回结构Controller层代码编写启动后postman测试接口功能GetMapping("/{id}")GetMapping("list")PostMappingPutMappingDeleteMapping("/{id}")getAllUserSor…

2026/10/28 10:29:22

《人不知而不愠:一场关于“关山”与“为己之学”的独立探索》

《人不知而不愠:一场关于“关山”与“为己之学”的独立探索》撰写这篇长篇学术评论的缘起,始于重读李晨阳教授的《与时俱进的人类原则——提倡一种研究儒学的新进路》。李先生在文中提出,儒学要与时俱进,只需把孟子的“核心立场”…

2026/10/28 10:29:22

物业费太贵怎么办?别死磕降价,这两条合规省钱路更实在

每次在业主群里看到有人问“物业费太贵怎么办”,底下总是一水儿的“成立业委会换物业”或“拒交抗议”。但现实很骨感。中指研究院今年10月发布的数据摆在那:2026年全国物业服务满意度均值掉到了72.8分,住宅物业费收缴率也一直在82.67%左右徘…

2026/10/28 10:24:17

命令模式思想与 EvSim 事件调度

命令模式把一次操作请求封装成对象,使请求能够被保存、传递、排队,并在合适的时候执行。本文结合 EvSim 的事件机制,说明事件如何表达动作,以及事件队列和世界对象如何共同完成调度。在程序中,执行一个动作最直接的方式…

2026/10/27 14:24:03

全国计算机二级C语言真题PDF高效刷题指南

简介:这份PDF是全国计算机二级C语言考试的试题与答案解析,专为备考二级C语言的考生准备。内容涵盖C语言特点与设计理念、程序基本组成单位、main函数执行流程、函数嵌套调用规则、标识符命名规范、整型实型字符型数据类型、八进制十六进制数合法形式、运…

2026/10/27 9:34:54

requests+BeautifulSoup:爬虫抓取h1标题的入门实战指南

简介:一份以实战为导向的Python爬虫入门资源,面向具备基本编程基础、希望快速掌握网络数据抓取的初学者,可解决从零编写简单爬虫的常见困惑。实例以requests库发送HTTP请求、BeautifulSoup解析HTML文档,完整演示从网页中提取 标题…

2026/10/28 3:32:29

递推最小二乘参数辨识MATLAB编程:二阶系统与渐消记忆实现

简介:这是一篇面向控制系统、信号处理与机器学习等领域学习者的最小二乘参数辨识程序说明文档。资源共包含一个docx格式文档,压缩包大小七十八KB,内容围绕递推最小二乘算法和渐消记忆最小二乘算法展开:先构造一个极点位于单位圆内…

2026/10/28 0:02:13

Python股票自动交易系统源码解析:从行情获取到风控的完整链路

简介:这份资源是面向高校计算机、金融相关专业毕业设计场景的完整项目源码包,主题为基于Python的股票自动交易系统,适合需要完成毕设选题、课程设计或自学金融量化交易开发的学生与开发者参考。压缩包共收录687个文件,整体约14.93…

2026/10/28 0:02:13

视酷酷信IM源码部署指南:Java 17+MySQL 8.0.33实战配置

简介:这是一套2024年亲测可部署的视酷酷信IM即时通讯系统源码,面向具备Java、OC、C#及Vue开发能力的技术人员,解决私有化即时通讯平台快速搭建与二次定制需求,尤其适用于需集成商城、保障数据主权的中小型企业或独立开发者。资源共…

2026/10/28 0:02:13

Python爬取百度迁徙数据:接口解析、批量采集与避坑指南

简介:这份资源是一个用Python爬取百度迁徙数据的脚本压缩包,面向具备Python基础、希望入门网络爬虫与数据解析的开发者,解决按日期获取全国热门城市人口迁徙数据的问题。包内共1个文件,为单个py脚本,压缩包约1KB&#…

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
☎咨询二维码 ☎ ↑