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

【C++】模拟实现vector

可以把vector看作升级版的数组,可采用下标进行访问,非常高效,大小可动态改变,会自动扩容,数据存储在堆空间上。

VECROR

  • 成员变量、函数及模板总览
  • 构造函数和析构函数
    • 无参构造函数
    • 构造n个元素大小的空间并初始化
    • 通过某个对象的两个迭代器来构造
    • 拷贝构造函数
    • 赋值运算符重载
    • 析构函数
  • 迭代器
    • 返回第一个元素迭代器
    • 返回最后一个元素迭代器
  • 容量和大小相关函数
    • 返回当前大小
    • 返回当前容量上限
    • reserve函数
    • resize函数
  • 访问元素接口
    • [ ]运算符重载
  • 添加元素与删除元素
    • 尾插
    • 指定位置插入元素
    • 删除指定位置元素
    • 尾删
    • 交换
  • 源代码

成员变量、函数及模板总览

namespace ahunb{template<class T>class vector{public:// Vector的迭代器是一个指针 //typedef T* iterator;typedef const T* const_iterator;/ Iterators /iterator begin();iterator end();const_iterator cbegin();const_iterator cend() const// construct and destroy vector()vector(int n, const T& value = T())template<class InputIterator>vector(InputIterator first, InputIterator last)vector(const vector<T>& v);vector<T>& operator= (vector<T> v)~vector()/ capacity /size_t size() const ;size_t capacity() constvoid reserve(size_t n)void resize(size_t n, const T& value = T())///Element access//T& operator[](size_t pos)const T& operator[](size_t pos)const///modifiers/void push_back(const T& x)void pop_back()void swap(vector<T>& v);iterator insert(iterator pos, const T& x);iterator erase(Iterator pos)private:iterator _start; // 指向数据块的开始iterator _finish; // 指向有效数据的尾iterator _endOfStorage; // 指向存储容量的尾};

构造函数和析构函数

无参构造函数

vector()
{}

构造n个元素大小的空间并初始化

vector(int n, const T& value = T())
{resize(n);for (int i = 0; i < n; i++){vector[i] = value;}
}

通过某个对象的两个迭代器来构造

template<class InputIterator>vector(InputIterator first, InputIterator last)
{while (first != last){push_back(*first);first++;}
}

拷贝构造函数

vector(const vector<T>& v)
{reserve(v.capacity());for (auto e : v){push_back(e);}
}

赋值运算符重载

vector<T>& operator= (vector<T> v)
{swap(v);return *this;
}

析构函数

~vector()
{delete[] _start;_start = _finish = _endofstorage = nullptr;
}

迭代器

返回第一个元素迭代器

多提供一个加const的 ,以防有const对象要调用

iterator begin()
{return _start;
}
const_iterator begin() const
{return _start;
}

返回最后一个元素迭代器

iterator end()
{return _finish;
}
const_iterator end() const
{return _finish;
}

容量和大小相关函数

返回当前大小

size_t size()
{return _finish - _start;
}
const size_t size() const 
{return _finish - _start;
}

返回当前容量上限

size_t capacity()
{return _endofstorage - _start;
}const size_t capacity() const
{return _endofstorage - _start;
}

reserve函数

改变vector的capacity(容量)变量

当n>capacity将capacity改为n,否则不变

对新空间进行拷贝时要深拷贝,否则delete时会出现野指针

在这里插入图片描述

void reserve(size_t n)
{if (n > capacity()){int sz = size();iterator tmp = new T[n];if (_start){for (int i = 0; i < sz; i++){tmp[i] = _start[i];//注意使用深拷贝}delete[]  _start;}_start = tmp;_finish = _start + sz;_endofstorage = _start+n;}
}

resize函数

改变vector的size(当前大小)变量

当n>size时,将大小改为n,并将新增加的大小初始化

否则直接将大小改为n就可以

void resize(size_t n, const T& value = T())
{if (n > size()){reserve(n);while (_finish < _start + n){*_finish = value;_finish++;}}else{_finish = _start + n;}
}

访问元素接口

[ ]运算符重载

T& operator[](size_t pos)
{assert(pos < size());return _start[pos];
}const T& operator[](size_t pos)const
{assert(pos < size());return _start[pos];
}

添加元素与删除元素

尾插

void push_back(const T& x)
{if (_finish == _endofstorage){int cp = capacity();cp = (cp == 0 ? 4 : cp * 2);reserve(cp);}*_finish = x;++_finish;
}

指定位置插入元素

  • 注意扩容之后会存在pos失效问题,因为扩容之后原对象改变了_start等指针,指向了新的区间,但pos指向的还是原来的区间,所以在第七行和第九行对pos进行了更新。
iterator insert(iterator pos, const T& x)
{assert(pos <= finish);assert(pos >= _start);if (_finish == _endofstorage){int n = pos - _start;reserve(capacity() + 1);pos = _start + n;}iterator end = _finish;while (end > pos){*end = *(end - 1);end--;}*pos = x;_finish++;return pos;
}

删除指定位置元素

iterator erase(iterator pos)
{assert(pos < finish);assert(pos >= _start);if (_finish - 1 != pos){iterator begin = pos;while (begin < _finish - 1){*begin = *(begin + 1);}}_finish--;return pos+1;
}

尾删

void pop_back()
{erase(_finish - 1);
}

交换

void swap(vector<T>& v)
{std::swap(_start, v._start);std::swap(_finish, v._finish);std::swap(_endofstorage, v._endofstorage);
}

源代码

//vector.h
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <assert.h>using namespace std;namespace ahu 
{template <class T>class vector {public:typedef T* iterator;typedef const T* const_iterator;vector(){}vector(int n, const T& value = T()){resize(n);for (int i = 0; i < n; i++){vector[i] = value;}}template<class InputIterator>vector(InputIterator first, InputIterator last){while (first != last){push_back(*first);first++;}}vector(const vector<T>& v){reserve(v.capacity());for (auto e : v){push_back(e);}}vector<T>& operator= (vector<T> v){swap(v);return *this;}~vector(){delete[] _start;_start = _finish = _endofstorage = nullptr;}//Iteratoriterator begin(){return _start;}iterator end(){return _finish;}const_iterator begin() const{return _start;}const_iterator end() const{return _finish;}//Capacitysize_t size(){return _finish - _start;}const size_t size() const {return _finish - _start;}size_t capacity(){return _endofstorage - _start;}const size_t capacity() const{return _endofstorage - _start;}void reserve(size_t n){if (n > capacity()){int sz = size();iterator tmp = new T[n];if (_start){for (int i = 0; i < sz; i++){tmp[i] = _start[i];}delete[]  _start;}_start = tmp;_finish = _start + sz;_endofstorage = _start+n;}}void resize(size_t n, const T& value = T()){if (n > size()){reserve(n);while (_finish < _start + n){*_finish = value;_finish++;}_finish = _start + n;}else{_finish = _start + n;}}//Element accessT& operator[](size_t pos){assert(pos < size());return _start[pos];}const T& operator[](size_t pos)const{assert(pos < size());return _start[pos];}//Modifiersvoid push_back(const T& x){if (_finish == _endofstorage){int cp = capacity();cp = (cp == 0 ? 4 : cp * 2);reserve(cp);}*_finish = x;++_finish;}void pop_back(){erase(_finish - 1);}void swap(vector<T>& v){std::swap(_start, v._start);std::swap(_finish, v._finish);std::swap(_endofstorage, v._endofstorage);}iterator insert(iterator pos, const T& x){assert(pos <= finish);assert(pos >= _start);if (_finish == _endofstorage){int n = pos - _start;reserve(capacity() + 1);pos = _start + n;}iterator end = _finish;while (end > pos){*end = *(end - 1);end--;}*pos = x;_finish++;return pos;}iterator erase(iterator pos){assert(pos < finish);assert(pos >= _start);if (_finish - 1 != pos){iterator begin = pos;while (begin < _finish - 1){*begin = *(begin + 1);}}_finish--;return pos+1;}private:iterator _start = nullptr; // 指向数据块的开始iterator _finish = nullptr; // 指向有效数据的尾iterator _endofstorage = nullptr; // 指向存储容量的尾};
}//vector.cpp
#define _CRT_SECURE_NO_WARNINGS
#include "vector.h"
//#include <vector>
using namespace ahu;
int main()
{vector<int> v1;v1.push_back(1);v1.push_back(1);v1.push_back(1);v1.push_back(1);v1.push_back(1);v1.push_back(1);v1.push_back(1);v1.push_back(1);//v1.push_back(1);vector<int> v2(v1);for (size_t i = 0; i < v2.size(); i++){cout << v2[i] << endl;}cout << "-------------------------------------" << endl;//v2.reserve(100);//cout << v2.capacity() << endl;//cout << v2.size()<<endl;//v2.resize(50);//cout << v2.capacity() << endl;//cout << v2.size() << endl;//v2.reserve(25);//cout << v2.capacity() << endl;//cout << v2.size() << endl;v2.insert(v2.begin()+3, 100);for (size_t i = 0; i < v2.size(); i++){cout << v2[i] << endl;}cout << "-------------------------------------" << endl;v2.erase(v2.begin() + 9);v2.erase(v2.begin() + 8);v2.erase(v2.begin() + 7);v2.erase(v2.begin() + 6);v2.erase(v2.begin() + 5);v2.erase(v2.begin() + 4);v2.erase(v2.begin()+3);for (size_t i = 0; i < v2.size(); i++){cout << v2[i] << endl;}
}

img

✨本文收录于C++语法及练习

当你喜欢一篇文章时,点赞、收藏和关注是最好的支持方式。如果你喜欢我的文章,请不要吝啬你的支持,点赞👍、收藏⭐和关注都是对我最好的鼓励。感谢你们的支持!如有问题欢迎指正!

相关文章:

【C++】模拟实现vector

可以把vector看作升级版的数组&#xff0c;可采用下标进行访问&#xff0c;非常高效&#xff0c;大小可动态改变&#xff0c;会自动扩容&#xff0c;数据存储在堆空间上。 VECROR 成员变量、函数及模板总览构造函数和析构函数无参构造函数构造n个元素大小的空间并初始化通过某个…...

【CAN-IDPS】汽车网关信息安全要求以及实验方法

《汽车网关信息安全技术要求及试验方法》是中国的一项国家标准,编号为GB/T 40857-2021,于2021年10月11日发布,并从2022年5月1日起开始实施 。这项标准由全国汽车标准化技术委员会(TC114)归口,智能网联汽车分会(TC114SC34)执行,主管部门为工业和信息化部。 该标准主要…...

EASE-Grid是啥东西?

EASE-Grid&#xff08;Equal-Area Scalable Earth Grid&#xff0c;等面积可扩展地球网格&#xff09;是NASA设计的网格系统&#xff0c;主要用于存储和处理全球范围内的地球科学数据。可以被理解为一种特殊的投影方式&#xff0c;使得在全球范围内进行数据分析和可视化时&…...

前端用户管理模块方法及api分析

用户管理 方法及对应api 搜索 searchSysUser / GetSysUserListByPage 重置 resetData 添加用户 addShow &#xff1a;点击按钮后出现对话框&#xff0c;含有提交 submit / SaveSysUser、取消按钮 修改 editSysUser / UpdateSysUser 删除 deleteById / DeleteSysUser 分配角色…...

microsoft edge怎么关闭安全搜索

microsoft edge浏览器为用户提供了安全搜索功能&#xff0c;旨在帮助用户过滤掉搜索结果中出现的不当信息。然而&#xff0c;有些用户可能觉得安全搜索功能限制了他们的浏览体验或工作需求。下面就给大家带来关闭microsoft edge安全搜索的相关内容&#xff0c;一起来看看吧。&a…...

Qt | QSQLite内存数据库增删改查

点击上方"蓝字"关注我们 01、演示 参数随便设置 查询 修改 右键菜单是重点 手动提交,点击Submit All...

【论文阅读】SegNeXt:重新思考卷积注意力设计

《SegNeXt: Rethinking Convolutional Attention Design for Semantic Segmentation》 原文&#xff1a;https://github.com/Visual-Attention-Network/SegNeXt/blob/main/resources/paper.pdf 源码&#xff1a;https://github.com/Visual-Attention-Network/SegNeXt 1、简介 …...

【C++】String类:标准库介绍

目录 一.预备知识 1.auto关键字 2.范围for 3.迭代器 二.标准库里的string 1.string类的基本介绍 2.构造函数 ​编辑 3.访问及遍历操作 3.1 operator [] 3.2 基于范围for 3.3 使用迭代器 4.迭代器 5.容量操作 5.1 size和length 5.2 capacity 5.3 reserve和resiz…...

MS523非接触式读卡器 IC

MS523 是一款应用于 13.56MHz 非接触式通信中的高集成 度读写卡芯片&#xff0c;它集成了在 13.56MHz 下所有类型的被动非接 触式通信方式和协议&#xff0c;支持 ISO14443A/B 的多层应用。 主要特点  高度集成的解调和解码模拟电路  采用少量外部器件&#…...

仓颉编程语言入门 -- Socket 编程与HTTP 编程概述

仓颉的 Socket 编程概述 在网络通信的广阔天地中&#xff0c;仓颉的Socket编程如同一座桥梁&#xff0c;连接着不同的计算设备&#xff0c;实现了基于传输层协议的数据传输。无论是追求稳定可靠的TCP&#xff0c;还是偏好轻量级、无连接的UDP&#xff0c;Socket都扮演着不可或…...

Oracle基本SQL操作-用户角色权限管理

一、用户权限管理 -- 创建锁定用户&#xff0c;此时用户不可用 create USER zhucl IDENTIFIED BY 123456 account lock; 会提示用户被锁定&#xff1a; -- 删除用户 drop user zhucl;-- 重新创建用户&#xff0c;不锁定 create user zhucl IDENTIFIED BY 123456 account unlo…...

Qt-信号和槽(8)

目录 信号的概念 Qt中的信号三要素 connect函数 connect的原型 connect的使用 信号函数和槽函数 参数匹配 close关闭槽函数 运行结果 第一个问题&#xff1a;怎么知道 手册使用 第二个问题&#xff0c;为什么可以直接传递函数指针 自定义槽函数 第一种自定义槽函…...

80.游戏的分辨率修改思路与分析

免责声明&#xff1a;内容仅供学习参考&#xff0c;请合法利用知识&#xff0c;禁止进行违法犯罪活动&#xff01; 内容参考于&#xff1a;易道云信息技术研究院 上一个内容&#xff1a;79.游戏分析工具闪屏问题优化与数据被修改高亮 GAMEHACKER2.exe 工具下载地址&#xff…...

MaxKB(二):Ubuntu24.04搭建maxkb开发环境

接上文&#xff1a;windows10搭建maxkb开发环境&#xff08;劝退指南&#xff09; 上文在windows10环境搭建maxkb开发环境遇到各种坑&#xff0c;后面就转战ubuntu平台&#xff0c;果然比较顺利的完成开发环境搭建。当然遇到相关的问题还是可以参考上文《windows10搭建maxkb开发…...

c#实现数据导出为PDF的方式

PdfSharp vs iTextSharp: C#中PDF导出功能比较 PdfSharp 优点 轻量级&#xff1a;适合简单的PDF生成任务易于学习&#xff1a;API相对简单&#xff0c;学习曲线较缓开源&#xff1a;提供开源版本&#xff0c;可自由使用和修改纯C#实现&#xff1a;不依赖外部库或COM组件支持…...

【联想电脑】:使用拓展坞后转接HDMI,无法识别显示屏

项目场景&#xff1a; 作为一个嵌入式软件开发者&#xff0c;有两个外接屏幕&#xff0c;不足为奇。 但是在今天的使用电脑过程中&#xff0c;出现了接了一个拓展坞上面有HDMI接口&#xff0c;但是HDMI接口接上外接显示屏的时候电脑无法识别到&#xff0c;导致只有电脑直连的HD…...

Verilog刷题笔记53

题目&#xff1a; Fsm serialdata See also: Serial receiver Now that you have a finite state machine that can identify when bytes are correctly received in a serial bitstream, add a datapath that will output the correctly-received data byte. out_byte needs …...

GoFly快速开发后台框架-后端接口请求返回403提示码就跨域问题/请求端域名拦截问题

问题&#xff1a; 大家在本地开发或者部署后请求后端时返回403&#xff0c;只有一个问题就是存在请求端跨域问题。 解决办法&#xff1a; 解决这个问题很简单&#xff0c;跨域的就解决跨域就好了。 我们官方给大家统一解决办法是&#xff1a; 到后端配置文件resource/conf…...

设备实时数据采集:开启制造业智能化、自动化的新篇章

传统制造业在进行生产过程中&#xff0c;会涉及到设备实时数据采集需求&#xff0c;这些数据对于监控生产流程、优化生产效率、保证产品质量以及降低成本等方面至关重要。以下是一些常见的数据采集需求&#xff1a; 1.生产数据&#xff1a;包括生产数量、生产批次、生产速度等&…...

【python与java的区别-03(集合、字典)】

一、Set python: 集合&#xff08;set&#xff09;是一个无序的不重复元素序列。 集合中的元素不会重复&#xff0c;并且可以进行交集、并集、差集等常见的集合操作。 可以使用大括号 { } 创建集合&#xff0c;元素之间用逗号 , 分隔&#xff0c; 或者也可以使用 set() 函数…...

Java继承

目录 一、继承概念 二、语法格式 三、类型及特性 四、关键字 4.1. super 4.2. super与this指针 4.3 final 关键字 一、继承概念 继承(inheritance)机制&#xff1a;是面向对象程序设计使代码可以复用的最重要的手段&#xff0c;它允许程序员在保持原有类特 性 的基础上进…...

Kafka集群搭建的两种方式

目录 1. 依赖Zookeeper搭建集群 1. 下载Kafka二进制文件 2. 更改kafka配置 3. 启动Zookeeper集群和Kafka集群 4. 验证集群 1.创建主题 2. 检查主题是否存在 3. 创建生产者生产数据 4. 创建消费者消费数据 5. 检查Zookeeper中Kafka集群的元数据 2. 不依赖Zookeeper搭…...

两种变量初始化方法的区别

1. CarriageEntity carriageEntity new CarriageEntity()和 null的区别 1.1 CarriageEntity carriageEntity new CarriageEntity(); 初始化&#xff1a;这行代码创建了一个新的 CarriageEntity 对象&#xff0c;并将其引用赋值给 carriageEntity 变量。对象状态&#xff…...

群晖把硬盘共享给win10(虚拟机或物理机)的两种办法

1. 通过SMB共享 NAS地址&#xff1a;192.168.3.100 打开“此电脑”&#xff0c;在win10地址栏输入 \192.168.3.100\video&#xff0c;提示输入用户名、密码。在video文件夹右击&#xff0c;点击“映射网络驱动器” 在win10电脑上&#xff0c;复制文件到T盘上&#xff0c;在T盘…...

Java-Web面试题汇总

一、TCP 和 UDP 的区别 在网络通信中&#xff0c;TCP&#xff08;Transmission Control Protocol&#xff0c;传输控制协议&#xff09;和 UDP&#xff08;User Datagram Protocol&#xff0c;用户数据报协议&#xff09;是两种常见的协议&#xff0c;它们在多个方面存在显著差…...

数字化技术分别有哪些,数字化技术特点和优势是什么?

​随着企业数字化进程的加速&#xff0c;人工智能、工业互联网、低代码等底层技术正全面重塑企业运营生产体系&#xff0c;推动新的生产要素、研发范式和商业模式的建立。 这个变革过程不仅是对原有制造体系的颠覆&#xff0c;而且会影响各行各业的所有细分行业和产业链价值链…...

微服务CI/CD实践(一)环境准备及虚拟机创建

微服务CI/CD实践系列&#xff1a; 微服务CI/CD实践&#xff08;一&#xff09;环境准备及虚拟机创建 微服务CI/CD实践&#xff08;二&#xff09;gitlabs部署 微服务CI/CD实践&#xff08;三&#xff09;nexus3部署 微服务CI/CD实践&#xff08;四&#xff09;数据库,redis,n…...

【SpringBoot】优化慢启动应用的用户体验

通过深入分析SpringBoot中WebServer的启动流程&#xff0c;插入自定义的Loading页面展示逻辑&#xff0c;优化软件使用时的用户体验。 背景 Java本身的特点&#xff0c;再加上开发人员能力差&#xff0c;软件开发工程化程度低等等问题&#xff0c;经过一段时间的迭代之后&…...

String str=“i“ 与 String str=new String (“i“) 一样吗?

String str"i" 与 String strnew String ("i") String str"i" 这种形式声明了一个 String 对象&#xff0c;其中 "i" 字符串字面量直接赋值给 str。在 Java 中&#xff0c;字符串字面量会自动放入字符串常量池中&#xff0c;这是一个…...

【数据结构】二叉树链式结构的实现

前置声明&#xff1a;在学习二叉树的基本操作前&#xff0c;需先要创建一棵二叉树&#xff0c;然后才能学习其相关的基本操作。由于现在大家对二叉树结构掌握还不够深入&#xff0c;为了降低大家学习成本&#xff0c;此处手动快速创建一棵简单的二叉树&#xff0c;快速进入二叉…...