当前位置: 首页 > 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() 函数…...

Phi-4-mini-reasoning自动化测试方案:生成测试数据与验证逻辑

Phi-4-mini-reasoning自动化测试方案&#xff1a;生成测试数据与验证逻辑 1. 引言&#xff1a;当AI遇上软件测试 最近跟几个测试团队聊天&#xff0c;发现他们都在为同样的事情头疼&#xff1a;手工编写测试用例耗时费力&#xff0c;边界条件覆盖不全&#xff0c;测试结果验证…...

TranslucentTB终极指南:3分钟打造Windows透明任务栏的完整教程

TranslucentTB终极指南&#xff1a;3分钟打造Windows透明任务栏的完整教程 【免费下载链接】TranslucentTB A lightweight utility that makes the Windows taskbar translucent/transparent. 项目地址: https://gitcode.com/gh_mirrors/tr/TranslucentTB 你是否厌倦了W…...

Apache NetBeans社区生态解析:如何参与贡献与获取支持

Apache NetBeans社区生态解析&#xff1a;如何参与贡献与获取支持 【免费下载链接】netbeans Apache NetBeans 项目地址: https://gitcode.com/gh_mirrors/ne/netbeans Apache NetBeans作为一个功能强大的开源IDE&#xff08;集成开发环境&#xff09;&#xff0c;拥有一…...

光伏混合储能直流微电网simulink模型 1.直流微电网由锂电池,超级电容,光伏和直流负载组成 2

光伏混合储能直流微电网simulink模型 1.直流微电网由锂电池&#xff0c;超级电容&#xff0c;光伏和直流负载组成 2.光伏采用电导增量法实现最大功率输出 3.锂电池和超级电容采用直流母线电压控制策略&#xff0c;根据直流母线电压高低实现充放电 实现以下目标&#xff1a; 1.光…...

【网络安全干货】黑客内网渗透零基础入门,超详细基础知识手把手教学

0x01 内网概述 内网也指局域网&#xff08;Local Area Network&#xff0c;LAN&#xff09;是指在某一区域内由多台计算机互联成的计算机组。一般是方圆几千米以内。局域网可以实现文件管理、应用软件共享、打印机共享、工作组内的历程安排、电子邮件和传真通信服务等功能。 内…...

OpenClaw+千问3.5-9B:个人知识库的自动构建与更新

OpenClaw千问3.5-9B&#xff1a;个人知识库的自动构建与更新 1. 为什么需要自动化知识管理 作为一个长期与技术文档打交道的开发者&#xff0c;我发现自己面临一个典型困境&#xff1a;每天接触大量有价值的信息——技术博客、论文片段、代码示例、会议记录——但它们最终都散…...

OpenClaw多账户管理:千问3.5-9B自动切换社交平台身份

OpenClaw多账户管理&#xff1a;千问3.5-9B自动切换社交平台身份 1. 为什么需要自动化多账户管理 作为一个长期运营多个社交媒体账号的内容创作者&#xff0c;我每天需要切换不同平台的账号身份。手动登录不仅耗时&#xff0c;还经常遇到浏览器缓存混乱导致账号异常的问题。更…...

Arduino嵌入式工具库解析:按键消抖、字符串格式化与I²C通信

1. 项目概述utils_asukiaaa是一个面向 Arduino 平台的轻量级工具函数库&#xff0c;聚焦于三类高频嵌入式开发场景&#xff1a;机械按键消抖与状态机管理、字符串格式化处理、IC 总线设备通信封装。该库采用 C 命名空间组织&#xff08;utils_asukiaaa::button/utils_asukiaaa:…...

24小时稳定运行方案:OpenClaw+Qwen3-32B进程守护配置

24小时稳定运行方案&#xff1a;OpenClawQwen3-32B进程守护配置 1. 为什么需要进程守护&#xff1f; 去年12月&#xff0c;我尝试用OpenClaw自动化处理每日技术简报时&#xff0c;遭遇了一个尴尬场景——凌晨3点任务突然中断&#xff0c;导致次日早晨的会议材料缺失关键数据。…...

3D 效果与深度:现代 UI 设计的立体革命

3D 效果与深度&#xff1a;现代 UI 设计的立体革命探索如何在 2024 年通过 CSS 和 Flutter 实现令人惊叹的 3D UI 效果&#xff0c;为用户界面增添深度和层次感。一、3D 设计的崛起 在当今的数字设计领域&#xff0c;平面化设计已经不再是唯一的选择。随着硬件性能的提升和浏览…...