c++系列之vector类模拟实现

在这里插入图片描述

💗 💗 博客:小怡同学
💗 💗 个人简介:编程小萌新
💗 💗 如果博客对大家有用的话,请点赞关注再收藏 🌞

构造函数

vector()


//_begin表示有效成员的开始
//_finish表示有效成员的大小
//_end表示有效的容积
vector():_begin(nullptr),_finish(nullptr),_end(nullptr){}

vector(size_t n, const T& value = T())

//这里不用memcpy拷贝的原因是
//1. memcpy是内存的二进制格式拷贝,将一段内存空间中内容原封不动的拷贝到另外一段内存空间中
//2. 如果拷贝的是内置类型的元素,memcpy既高效又不会出错,但如果拷贝的是自定义类型元素,并且自定义类型元素中涉及到资源管理时,就会出错,因为memcpy的拷贝实际是浅拷贝。
//3.内置类型也有拷贝构造
vector(int n, const T& value = T()):_begin(nullptr), _finish(nullptr), _end(nullptr){_begin = new T[n];_finish = _begin + n;_end = _begin + n;for (int i = 0; i < n; i++){*(_begin + i) = value;}}//便捷写法
/*vector(int n, const T& value = T())
{reserve(n);for (int i = 0; i < n; i++){_begin[i] =  value;}
}
vector(int n, const T& value = T())
{resize(n,value);
}*/

vector(InputIterator first, InputIterator last)

//迭代器构造
template<class InputIterator>
vector(InputIterator first, InputIterator last)
{while (first!= last){push_back(*first);//尾插first++;	}
}

vector(vector& v)

//拷贝构造
vector(vector<T>& v)
{size_t size = v._finish - v._begin;size_t capacity = v. _end - v._begin;_begin = new T[capacity];for (size_t i = 0; i < size; i++){*(_begin + i) = *(v._begin + i);}_finish = _begin + size;_end = _begin + capacity;	
}
//简便写法
vector(vector<T>& v)
{vector<T> tmp(v.begin(),v.end());swap(tmp);
}

析构函数

~vector()

~vector()
{if (_begin){delete[] _begin;_begin = _end = _finish = nullptr;}
}

运算符重载

vector& operator = (vector v)

//赋值拷贝
vector<T>& operator = (vector<T> v)
{swap(v);//这里传的是v的拷贝,改变v并不影响原本的对象return *this;
}

T& operator[](size_t pos);


T& operator[](size_t pos)
{assert(pos >= 0 && pos < size());//pos在有效范围种return _begin[pos];
}
//const对象调用
const T& operator[](size_t pos)const
{assert(pos >= _begin && pos < _finish);return _begin[pos];
}

查询vector容积和大小

size_t size()

size_t capacity()


size_t size() const
{return _finish - _begin;
}size_t capacity() const
{return _end - _begin;
}
size_t size()
{return _finish - _begin;
}size_t capacity()
{return _end - _begin;
}

调整vector的容积和大小

void reserve(size_t n)

void resize(size_t n, const T& value = T())


//这里发生扩容之后,原本的_begin,_finish,_end会发生改变,所以扩容之后要更新
void reserve(size_t n)
{if(n > capacity()){size_t oldsize = size();T* tmp = new T[n];for (size_t i = 0; i < oldsize; i++){tmp[i]  = _begin[i];}delete[] _begin;_begin = tmp;_finish = tmp +oldsize;_end = tmp + n;}
}void resize(size_t n, const T& value = T())
{if (n < size()){_finish = _begin + n;}else{if (n > capacity()){reserve(n);}while(_finish < _begin + n){*(_finish++) = value;}}
}

修改vector(头插,尾插,插入,删除,交换)

void push_back(const T& x)

void pop_back()

iterator insert(iterator pos, const T& x)

iterator erase(iterator pos)

void swap(vector& v)

void push_back(const T& x)
{if (_finish == _end){reserve(capacity() == 0? 4: capacity()*2);}*_finish =  x;_finish++;}void pop_back()
{assert(_begin != _finish);_finish--;
}
//这里会发生迭代器失效问题、
//原因1:如果发生扩容函数里原pos会变成野指针需要及时更新,函数外pos不会改变,所以要返回pos的新指针
//原因2.因为插入数据,原本pos意义改变,所以要及时更新,让pos指向新插入的元素
//正确做法是返回迭代器插入的指针
iterator insert(iterator pos, const T& x)
{assert(pos >= _begin && pos <= _finish);if (_finish == _end){size_t size = pos - _begin;reserve(capacity() == 0 ? 4 : capacity() * 2);pos = _begin + size;}iterator end = _finish - 1;while (end >= pos){*(end +1) = *(end);end--;}*pos = x;_finish++;return pos;
}
//迭代器失效原因1.erase删除pos位置元素后,pos位置之后的元素会往前搬移,没有导致底层空间的改变,理论上讲迭代器不应该会失效,但是:如果pos刚好是最后一个元素,删完之后pos刚好是end的位置,而end位置是没有元素的,那么pos就失效了。因此删除vector中任意位置上元素时,vs就认为该位置迭代器失效了。
//迭代器失效原因2:erase之后pos位置的意义改变,迭代器所以要更新
//正确做法是返回迭代器下一个的指针
iterator erase(iterator pos)
{assert(pos >= _begin && pos <_finish );iterator end = pos + 1;while (end < _finish){*(end - 1) = *(end);end++;}_finish--;return pos;
}
void swap(vector<T>& v)
{std::swap(_begin,v._begin);std::swap(_finish,v._finish);std::swap(_end,v._end);
}

vector的迭代器

typedef T* iterator;
typedef const T* const_iterator;

完整代码

namespace zjy
{template<class T>class vector{public:typedef T* iterator;typedef const T* const_iterator;iterator begin(){return _begin;}iterator end(){return _finish;}const_iterator cbegin(){return _begin();}const_iterator cend() const{return _finish;}vector():_begin(nullptr),_finish(nullptr),_end(nullptr){}vector(int n, const T& value = T()):_begin(nullptr), _finish(nullptr), _end(nullptr){_begin = new T[n];_finish = _begin + n;_end = _begin + n;for (int i = 0; i < n; i++){*(_begin + i) = value;}}//vector(int n, const T& value = T())//{//	reserve(n);//	for (int i = 0; i < n; i++)//	{//		_begin[i] =  value;//	}//}//vector(int n, const T& value = T())//{//	resize(n,value);//}template<class InputIterator>vector(InputIterator first, InputIterator last){while (first!= last){push_back(*first);first++;}}vector(vector<T>& v){size_t size = v._finish - v._begin;size_t capacity = v. _end - v._begin;_begin = new T[capacity];for (size_t i = 0; i < size; i++){*(_begin + i) = *(v._begin + i);}_finish = _begin + size;_end = _begin + capacity;}//vector(vector<T>& v)//{//	vector<T> tmp(v.begin(),v.end());//	swap(tmp);//}vector<T>& operator = (vector<T> v){swap(v);return *this;}~vector(){if (_begin){delete[] _begin;_begin = _end = _finish = nullptr;}}size_t size() const{return _finish - _begin;}size_t capacity() const{return _end - _begin;}void reserve(size_t n){if(n > capacity()){size_t oldsize = size();T* tmp = new T[n];for (size_t i = 0; i < oldsize; i++){tmp[i]  = _begin[i];}delete[] _begin;_begin = tmp;_finish = tmp +oldsize;_end = tmp + n;}}void resize(size_t n, const T& value = T()){if (n < size()){_finish = _begin + n;}else{if (n > capacity()){reserve(n);}while(_finish < _begin + n){*(_finish++) = value;}}}T& operator[](size_t pos){assert(pos >= 0 && pos < size());return _begin[pos];}const T& operator[](size_t pos)const{assert(pos >= _begin && pos < _finish);return _begin[pos];}void push_back(const T& x){if (_finish == _end){reserve(capacity() == 0? 4: capacity()*2);}*_finish =  x;_finish++;}void pop_back(){assert(_begin != _finish);_finish--;}void swap(vector<T>& v){std::swap(_begin,v._begin);std::swap(_finish,v._finish);std::swap(_end,v._end);}iterator insert(iterator pos, const T& x){assert(pos >= _begin && pos <= _finish);if (_finish == _end){size_t size = pos - _begin;reserve(capacity() == 0 ? 4 : capacity() * 2);pos = _begin + size;}iterator end = _finish - 1;while (end >= pos){*(end +1) = *(end);end--;}*pos = x;_finish++;return pos;}iterator erase(iterator pos){assert(pos >= _begin && pos <_finish );iterator end = pos + 1;while (end < _finish){*(end - 1) = *(end);end++;}_finish--;return pos;}private:T* _begin = nullptr;T* _finish = nullptr;T* _end = nullptr;};
}

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/171025.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

配置Sentinel 控制台

1.遇到的问题 服务网关 | RuoYi 最近调试若依的微服务版本需要用到Sentinel这个组件&#xff0c;若依内部继承了这个组件连上即用。 Sentinel是阿里巴巴开源的限流器熔断器&#xff0c;并且带有可视化操作界面。 在日常开发中&#xff0c;限流功能时常被使用&#xff0c;用…

力扣:142. 环形链表 II(Python3)

题目&#xff1a; 给定一个链表的头节点 head &#xff0c;返回链表开始入环的第一个节点。 如果链表无环&#xff0c;则返回 null。 如果链表中有某个节点&#xff0c;可以通过连续跟踪 next 指针再次到达&#xff0c;则链表中存在环。 为了表示给定链表中的环&#xff0c;评…

第13期 | GPTSecurity周报

GPTSecurity是一个涵盖了前沿学术研究和实践经验分享的社区&#xff0c;集成了生成预训练 Transformer&#xff08;GPT&#xff09;、人工智能生成内容&#xff08;AIGC&#xff09;以及大型语言模型&#xff08;LLM&#xff09;等安全领域应用的知识。在这里&#xff0c;您可以…

k8s 金丝雀发布与声明式管理

Deployment控制器支持自定义控制更新过程中的滚动节奏&#xff0c;如“暂停(pause)”或“继续(resume)”更新操作。比如等待第一批新的Pod资源创建完成后立即暂停更新过程&#xff0c;此时&#xff0c;仅存在一部分新版本的应用&#xff0c;主体部分还是旧的版本。然后&#xf…

Vue+el-image-viewer显示tiff图片,并能够切换图片中的帧

一、简述 在前端界面显示tiff图片&#xff0c;并能够点击翻页按钮切换tiff图片中的帧&#xff0c;接收到后端传来的buffer&#xff0c;在前端处理后进行展示 二、使用工具 引入Tiff.js文件&#xff0c;引入前先进行下载安装 import Tiff from tiff.js引入显示图片组件 comp…

【牛牛送书 | 第二期】《ChatGPT 驱动软件开发:AI 在软件研发全流程中的革新与实践》

目录 前言&#xff1a; 本书目录&#xff1a; 内容简介&#xff1a; 专家评价&#xff1a; 适合对象&#xff1a; 送书规则&#xff1a; 前言&#xff1a; 现如今&#xff0c;随着计算机技术的不断发展和互联网的普及&#xff0c;我们已经迈入了一个高效的信息处理和传…

常用的网络攻击手段

前言&#xff1a;本文旨在介绍目前常用的网络攻击手段&#xff0c;分享交流技术经验 目前常用的网络攻击手段 社会工程学攻击物理攻击暴力攻击利用Unicode漏洞攻击利用缓冲区溢出漏洞进行攻击等技术 社会工程学攻击 社会工程学 根据百度百科定义&#xff1a; 社会工…

北邮22级信通院数电:Verilog-FPGA(7)第七周实验(1):带使能端的38译码器全加器(关注我的uu们加群咯~)

北邮22信通一枚~ 跟随课程进度更新北邮信通院数字系统设计的笔记、代码和文章 持续关注作者 迎接数电实验学习~ 获取更多文章&#xff0c;请访问专栏&#xff1a; 北邮22级信通院数电实验_青山如墨雨如画的博客-CSDN博客 关注作者的uu们可以进群啦~ 目录 方法一&#xff…

面试题之Vue和React的区别是什么?

一提到前端框架&#xff0c;相信大家都对Vue和React不陌生&#xff0c;这两个前端框架都是比较主流的&#xff0c;用户也都比较多&#xff0c;但是我们在使用这些框架的时候&#xff0c;是否对这两个框架之间的区别有所了解呢&#xff1f;接下来&#xff0c;让我们来一起的系统…

大模型如何商业变现?小i机器人发布华藏大模型生态

华藏通用大模型生态体系由“113”三部分组分&#xff0c;即&#xff1a;一个能力基座一项产品支撑三项服务保障。 今年以来&#xff0c;市场上各类人工智能大模型如雨后春笋&#xff0c;但如何将大模型进行科学的商业变现&#xff0c;成为摆在行业面前的一道难题。在刚刚召开的…

使用pytest和allure框架实现自动化测试报告优化

pytest&#xff1a; 需要安装pytest和pytest-html(生成html测试报告&#xff09; pip install pytest 和 pip install pytest-html 命名规则 Pytest单元测试中的类名和方法名必须是以test开头,执行中只能找到test开头的类和方法&#xff0c;比unittest更加严谨 unittest&#x…

微前端qiankun接入Vue和React项目

主应用&#xff1a;Vue3Webpack 1、创建主应用&#xff1a; npx vue create main-vue3-app 2、安装qiankun npx yarn add qiankun 3、项目中使用的vue、vue-router、qiankun依赖如下&#xff0c;webpack版本为5.x 4、在根目录下创建vue.config.js const { defineConfig }…

Map集合 遍历:lambda方式

package day01;import java.util.*;public class Mapday1 {public static void main(String[] args) {/* HashMap 无序 不重复&#xff0c;会覆盖前面 无索引*/System.out.println("--------------------");Map<String, Integer> map new HashMap<>();m…

UE4/5 竖排文字文本

方法一、使用多行文本组件 新建一个Widget Blueprint 添加Text 或者 Editable Text(Multi-Line) 、TextBox(Multi-Line) 组件。 添加文字&#xff0c;调整字号&#xff0c;调整成竖排文字。 在Wrapping &#xff08;换行&#xff09;面板中 &#xff1a; 勾选 Auto Wrap te…

eslint提示 xxx should be listed in the project's dependencies

有时候手动安装了一个npm包A&#xff0c;npm包A里面包含了npm包B&#xff0c;这时候如果 import xxx from npm包B;eslint会报错&#xff0c;提示 npm包B 不在 package.json 里面 解决方法&#xff1a;在 eslintrc.js 增加配置 module.exports {rules: {import/no-extraneous-d…

J2EE项目部署与发布(Windows版本)

目录 一.会议OA单体项目Windows部署 1.实操 二.spa前后端分离项目Windows部署 1.部署后端 2.部署前端 配置node.js 3.从实施的角度 4.从开发的角度 ​编辑 一.会议OA单体项目Windows部署 我们从实施的角度来看&#xff0c;拿到项目之后一定要问开发人员提供数据库脚…

TypeScript学习 | 泛型

简介 泛型是指在定义函数、接口或类的时候&#xff0c;不预先指定具体的类型&#xff0c;而在使用的时候再指定类型的一种特性 作用 可以保证类型安全的前提下&#xff0c;让函数、接口或类与多种类型一起工作&#xff0c;从而实现复用 基本使用 举个例子&#xff1a; 创…

Java练习题2021-4

"某游戏公司设计了一个奖励活动&#xff0c;给N个用户(1≤N≤10^7)连续编号为1到N&#xff0c;依据用户的编号S发放奖励。 发放奖励规则为&#xff1a; 公司随机设定三个非零正整数x&#xff0c;y&#xff0c;z。 如果S同时是x、y的倍数&#xff0c;奖励2张卡片&#xff1…

ChinaSoft 论坛巡礼 | 开源软件生态健康度量论坛

2023年CCF中国软件大会&#xff08;CCF ChinaSoft 2023&#xff09;由CCF主办&#xff0c;CCF系统软件专委会、形式化方法专委会、软件工程专委会以及复旦大学联合承办&#xff0c;将于2023年12月1-3日在上海国际会议中心举行。 本次大会主题是“智能化软件创新推动数字经济与社…

React中的受控组件(controlled component)和非受控组件(uncontrolled component)

聚沙成塔每天进步一点点 ⭐ 专栏简介 前端入门之旅&#xff1a;探索Web开发的奇妙世界 欢迎来到前端入门之旅&#xff01;感兴趣的可以订阅本专栏哦&#xff01;这个专栏是为那些对Web开发感兴趣、刚刚踏入前端领域的朋友们量身打造的。无论你是完全的新手还是有一些基础的开发…