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

C++ 中的 vector 的模拟实现【代码纯享】

文章目录

  • C++ 中的 vector 模拟实现
    • 1. vector 的基本概念
    • 2. vector 的基本操作
    • 3. vector 的模拟实现
    • 4.代码纯享
    • 5. 总结

C++ 中的 vector 模拟实现

在 C++ 中,vector 是一个非常重要的容器,它提供了动态数组的功能。在本篇博客中,我们将尝试模拟实现一个简单的 vector 类,以便更好地理解其内部工作机制。

1. vector 的基本概念

vector 是一个封装了动态大小数组的顺序容器。与普通数组不同,vector 的大小可以根据需要动态地增加或减少,而不需要程序员手动管理内存。

2. vector 的基本操作

  • 构造函数:创建一个空的 vector 或者根据给定的初始值创建一个 vector
  • 赋值操作:将一个 vector 的内容赋值给另一个 vector
  • 访问元素:通过索引访问 vector 中的元素。
  • 插入和删除元素:在 vector 的任何位置插入或删除元素。
  • 大小操作:获取 vector 的大小或检查它是否为空。
  • 迭代器操作:提供迭代器以遍历 vector 中的元素。

3. vector 的模拟实现

首先,我们需要定义vector的基本结构。由于vector可以存储不同类型的元素,我们使用类模板来定义它:

namespace my_vector
{template<class T>class vector{public:// 定义迭代器类型typedef T* iterator;// 定义const迭代器类型typedef const T* const_iterator;// 其他成员变量和成员函数...
};

接下来,我们实现vector的一些基本成员函数,如默认构造函数,析构函数,拷贝构造函数:

		iterator begin(){return _start;}iterator end(){return _finish;}const_iterator begin() const{return _start;}const_iterator end() const{return _finish;}vector(){}//拷贝构造v2(v1)vector(const vector<T>& v){reserve(v.capacity());for (auto& e : v){push_back(e);}}//vector<int> v1 = { 1, 2, 3, 4, 5, 6, 7, 8 };//构造+拷贝构造 -> 优化 直接构造vector(initializer_list<T> il){reserve(il.size());for (auto& e : il){push_back(e);}}vector(size_t n, const T& val = T()){reserve(n);for (size_t i = 0; i < n; i++){push_back(val);}}vector(int n, const T& val = T()){reserve(n);for (int i = 0; i < n; i++){push_back(val);}}//深拷贝 v1=v3vector<T>& operator=(vector<T> v){swap(v);return *this;}~vector(){delete[] _start;_start = _finish = _endofstorage = nullptr;}
private:iterator _start = nullptr;iterator _finish = nullptr;iterator _endofstorage = nullptr;

然后,我们实现vector的迭代器。迭代器是一种行为类似于指针的对象,它能够遍历容器中的元素:

		bool empty(){return _start == _finish;}void insert(iterator pos, const T& val){assert(pos >= _start);assert(pos <= _finish);if (_finish == _endofstorage){size_t len = pos - _start;reserve(capacity() == 0 ? 4 : capacity() * 2);//如果扩容了要更新pospos = _start + len;}iterator it = _finish - 1;while (it >= pos){*(it + 1) = *it;it--;}*pos = val;_finish++;}iterator erase(iterator pos){assert(pos >= _start);assert(pos < _finish);iterator it = pos + 1;while (it < _finish){*(it - 1) = *it;it++;}--_finish;return pos;}

最后,我们实现vector的一些基本操作,如push_back、pop_back、begin、end等:

size_t size() const{return _finish - _start;}T& operator[](size_t pos){assert(pos < size());return _start[pos];}const T& operator[](size_t pos) const{assert(pos < size());return _start[pos];}size_t capacity() const {return _endofstorage - _start;}void reserve(size_t n){if (n > capacity()){T* tmp = new T[n];size_t old_size = size();//memcpy(tmp, _start, size()*sizeof(T));for (size_t i = 0; i < old_size; i++){tmp[i] = _start[i];}delete[] _start;_start = tmp;_finish = tmp + old_size;_endofstorage = tmp + n;}}void resize(size_t n,const T& val=T()){if (n > size()){reserve(n);//插入while (_finish<_start + n){*_finish = val;_finish++;}}else{//删除_finish = _start + n;}}void push_back(const T& val){/*if (_finish == _endofstorage){reserve(capacity() == 0 ? 4 : capacity() * 2);}*_finsh = val;_finsh++;*/insert(end(), val);}void pop_back(){/*assert(empty());_finsh--;*/erase(--end());}

4.代码纯享

#pragma once
#include <assert.h>namespace my_vector
{template<class T>class vector{public:// 定义迭代器类型typedef T* iterator;// 定义const迭代器类型typedef const T* const_iterator;// 其他成员变量和成员函数...iterator begin(){return _start;}iterator end(){return _finish;}const_iterator begin() const{return _start;}const_iterator end() const{return _finish;}vector(){}//拷贝构造v2(v1)vector(const vector<T>& v){reserve(v.capacity());for (auto& e : v){push_back(e);}}//vector<int> v1 = { 1, 2, 3, 4, 5, 6, 7, 8 };//构造+拷贝构造 -> 优化 直接构造vector(initializer_list<T> il){reserve(il.size());for (auto& e : il){push_back(e);}}//类模板的成员函数可以是函数模板template <class InputIerator>vector(InputIerator first, InputIerator last){while (first != last){push_back(*first);first++;}}vector(size_t n, const T& val = T()){reserve(n);for (size_t i = 0; i < n; i++){push_back(val);}}vector(int n, const T& val = T()){reserve(n);for (int i = 0; i < n; i++){push_back(val);}}void swap(vector<T>& v){std::swap(_start, v._start);std::swap(_finsh, v._finsh);std::swap(_endofstorage, v._endofstorage);}//深拷贝 v1=v3vector<T>& operator=(vector<T> v){swap(v);return *this;}~vector(){delete[] _start;_start = _finish = _endofstorage = nullptr;}size_t size() const{return _finish - _start;}T& operator[](size_t pos){assert(pos < size());return _start[pos];}const T& operator[](size_t pos) const{assert(pos < size());return _start[pos];}size_t capacity() const {return _endofstorage - _start;}void reserve(size_t n){if (n > capacity()){T* tmp = new T[n];size_t old_size = size();//memcpy(tmp, _start, size()*sizeof(T));for (size_t i = 0; i < old_size; i++){tmp[i] = _start[i];}delete[] _start;_start = tmp;_finish = tmp + old_size;_endofstorage = tmp + n;}}void resize(size_t n,const T& val=T()){if (n > size()){reserve(n);//插入while (_finish<_start + n){*_finish = val;_finish++;}}else{//删除_finish = _start + n;}}void push_back(const T& val){/*if (_finish == _endofstorage){reserve(capacity() == 0 ? 4 : capacity() * 2);}*_finsh = val;_finsh++;*/insert(end(), val);}void pop_back(){/*assert(empty());_finsh--;*/erase(--end());}bool empty(){return _start == _finish;}void insert(iterator pos, const T& val){assert(pos >= _start);assert(pos <= _finish);if (_finish == _endofstorage){size_t len = pos - _start;reserve(capacity() == 0 ? 4 : capacity() * 2);//如果扩容了要更新pospos = _start + len;}iterator it = _finish - 1;while (it >= pos){*(it + 1) = *it;it--;}*pos = val;_finish++;}iterator erase(iterator pos){assert(pos >= _start);assert(pos < _finish);iterator it = pos + 1;while (it < _finish){*(it - 1) = *it;it++;}--_finish;return pos;}private:iterator _start = nullptr;iterator _finish = nullptr;iterator _endofstorage = nullptr;};//函数模板//template <typename T>template <class T>void print_vector(const vector<T>& v){for (size_t i = 0; i < v.size(); i++){cout << v[i] << " ";}cout << endl;//typename vector<int>::const_iterator it = v.begin();//	auto it = v.begin();//	while (it != v.end())//	{//		cout << *it << " ";//		it++;//	}//	cout << endl;//	for (auto e : v)//	{//		cout << e << " ";//	}//	cout << endl;}void test_vector1(){vector<int> v1;v1.push_back(1);v1.push_back(2);v1.push_back(3);v1.push_back(4);v1.push_back(5);v1.push_back(6);print_vector(v1);v1.insert(v1.begin(),3);v1.insert(v1.begin() + 2, 3);v1.insert(v1.begin() + 4, 3);v1.insert(v1.begin() + 6, 3);print_vector(v1);v1.erase(v1.begin()+4);print_vector(v1);vector<double> v2;v2.push_back(0.1);v2.push_back(0.2);v2.push_back(0.3);v2.push_back(0.4);v2.push_back(0.5);v2.push_back(0.6);print_vector(v2);}void test_vector2(){vector<int> v1;v1.push_back(1);v1.push_back(2);v1.push_back(3);v1.push_back(4);v1.push_back(5);v1.push_back(6);print_vector(v1);v1.resize(10);print_vector(v1);v1.resize(3);print_vector(v1);}void test_vector3(){vector<int> v3(10,1);print_vector(v3);}void test_vector4(){auto x = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };cout << typeid(x).name() << endl;cout << sizeof(x) << endl;initializer_list<int> y = { 1, 2, 3, 4, 5, 6, 7 };//单参数的构造函数,隐式类型转换string str = "111111";//构造+拷贝构造->优化 直接构造const string& str1 = "111111";//构造+拷贝构造->优化 直接构造vector<string> v;v.push_back(str);v.push_back(string("22222"));v.push_back("33333");int i = 1;//不推荐 --- C++11int j = { 1 };int k{ 1 };//跟上面类似//隐式转化+优化vector<int> v1 = { 1, 2, 3, 4, 5, 6, 7, 8 };for (auto e : v1){cout << e << " ";}cout << endl;//直接构造vector<int> v2({ 1, 2, 3, 10, 20, 30 });for (auto e : v2){cout << e << " ";}cout << endl;}void test_vector5(){vector<string> v;v.push_back("11111");v.push_back("11111");v.push_back("11111");v.push_back("11111");v.push_back("11111");v.push_back("11111");for (auto& e : v){cout << e << " ";}cout << endl;}void test_vector6(){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);print_vector(v1);vector<int>::iterator it = v1.begin() + 3;v1.insert(it, 40);print_vector(v1);}
}

5. 总结

通过这个简单的 vector 模拟实现,我们不仅加深了对 vector 容器的理解,还学习了如何在 C++ 中实现一个动态数组。当然,实际的 vector 类还包含更多的功能和优化,我这个只是进行了简单的实现

相关文章:

C++ 中的 vector 的模拟实现【代码纯享】

文章目录 C 中的 vector 模拟实现1. vector 的基本概念2. vector 的基本操作3. vector 的模拟实现4.代码纯享5. 总结 C 中的 vector 模拟实现 在 C 中&#xff0c;vector 是一个非常重要的容器&#xff0c;它提供了动态数组的功能。在本篇博客中&#xff0c;我们将尝试模拟实现…...

UE4 方块排序动画

【动画效果】 入动画&#xff1a; 出动画&#xff1a; 【分析】 入动画&#xff1a;方块动画排序方式为Z字形&#xff0c;堆砌方向为X和Y轴向 出动画&#xff1a;方块动画排序方式为随机 【关键蓝图】 1.构建方块砌体 2.入/出动画...

网络与并发编程(一)

并发编程介绍_串行_并行_并发的区别 串行、并行与并发的区别 串行(serial)&#xff1a;一个CPU上&#xff0c;按顺序完成多个任务并行(parallelism)&#xff1a;指的是任务数小于等于cpu核数&#xff0c;即任务真的是一起执行的并发(concurrency)&#xff1a;一个CPU采用时间…...

超详细工具Navicat安装教程

Navicat是一款功能强大的数据库管理工具&#xff0c;可用于管理多种类型的数据库&#xff0c;包括MySQL、MariaDB、SQL Server、SQLite、Oracle和PostgreSQL等。以下是Navicat工具的一些主要特点和功能&#xff1a; 一.功能介绍 跨平台支持 多种数据库支持 直观的用户界面 数据…...

RN在android/ios手机剪切图片的操作

之前写过一个React Native调用摄像头画面及拍照和保存图片到相册全流程但是这个仅限于调用摄像头拍照并保存图片,今天再写一个版本的操作,这个博客目前实现的有三点操作: 调用摄像头拍照对照片进行剪切从相册选取图片 功能上面来说有两点: 点击按钮可以对摄像头进行拍照,拍完照…...

C语言 | Leetcode C语言题解之第6题Z字形变换

题目&#xff1a; 题解&#xff1a; char * convert(char * s, int numRows){int n strlen(s), r numRows;if (r 1 || r > n) {return s;}int t r * 2 - 2;char * ans (char *)malloc(sizeof(char) * (n 1));int pos 0;for (int i 0; i < r; i) { // 枚举矩阵的…...

C 回调函数的两种使用方法

对回调&#xff08;callback&#xff09;函数的一点粗陋理解&#xff0c;在我小时候&#xff0c;隔壁村有家月饼小作坊&#xff08;只在中秋那段时间手工制作一些月饼出售&#xff0c;后来好像不做了&#xff09;&#xff0c;做出的月饼是那种很传统很经典的款式&#xff0c;里…...

医院云HIS系统源码,二级医院、专科医院his系统源码,经扩展后能够应用于医联体/医共体

基于云计算技术的B/S架构的HIS系统&#xff0c;为医疗机构提供标准化的、信息化的、可共享的医疗信息管理系统&#xff0c;实现医患事务管理和临床诊疗管理等标准医疗管理信息系统的功能。 系统利用云计算平台的技术优势&#xff0c;建立统一的云HIS、云病历、云LIS&#xff0…...

NineData云原生智能数据管理平台新功能发布|2024年3月版

数据库 DevOps - 大功能升级 SQL 开发早期主要提供 SQL 窗口&#xff08;IDE&#xff09;功能&#xff0c;在产品经过将近两年时间的打磨&#xff0c;新增了大量的企业级功能&#xff0c;已经服务了上万开发者&#xff0c;覆盖了数据库设计、开发、测试、变更等生命周期的功能…...

java Web 疫苗预约管理系统用eclipse定制开发mysql数据库BS模式java编程jdbc

一、源码特点 JSP 疫苗预约管理系统是一套完善的web设计系统&#xff0c;对理解JSP java 编程开发语言有帮助&#xff0c;系统具有完整的源代码和数据库&#xff0c;系统主要采用B/S模式开发。开发环境为TOMCAT7.0,eclipse开发&#xff0c;数据库为Mysql5.0&#xff0c;使…...

Qt5.14.2 揭秘Qt日志神器高效诊断程序潜在隐疾

对程序员而言&#xff0c;代码中的bug往往如同无影无踪的隐疾&#xff0c;影响着程序的健康运行。而及时有效的诊断手段则是治疗这些隐疾的良药。今天&#xff0c;我们将一窥Qt日志框架QLoggingCategory的神奇功效&#xff0c;探究它如何为你的Qt应用程序构筑坚实的诊断防火墙。…...

Mac上设置环境变量PATH

一、配置文件有哪些 在Mac系统中&#xff0c;环境变量的配置文件主要包括以下几个&#xff1a; 文件名称描述/etc/paths系统级别的配置文件&#xff0c;系统启动时会加载它。/etc/profile系统级别的配置文件&#xff0c;所有用户登录时都会读取该文件。~/.bash_profile用户级别…...

Redis 全景图(1)--- 关于 Redis 的6大模块

这是我第一次尝试以长文的形式写一篇 Redis 的总结文章。这篇文章我想写很久了&#xff0c;只是一直碍于我对 Redis 的掌握没有那么的好&#xff0c;因此迟迟未动笔。这几天&#xff0c;我一直在看各种不同类型的 Redis 文章&#xff0c;通过阅读这些文章&#xff0c;引发了我对…...

Lambda表达式,Stream流

文章目录 Lambda表达式作用前提函数式接口特点 语法省略模式和匿名对象类的区别 Stream流思想作用三类方法获取方法单列集合(Collection[List,Set双列集合Map(不能直接获取)数组同一类型元素(Stream中的静态方法) 常见的中间方法终结方法收集方法 Optional类 Lambda表达式 作用…...

Apache Hive的基本使用语法(一)

一、数据库操作 创建数据库 create database if not exists myhive;查看数据库 use myhive; desc database myhive;创建数据库并指定hdfs存储 create database myhive2 location /myhive2;删除空数据库&#xff08;如果有表会报错&#xff09; drop database myhive;…...

Python爬虫详解:原理、常用库与实战案例

前言 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家&#xff1a;https://www.captainbed.cn/z ChatGPT体验地址 文章目录 前言引言&#xff1a;一、爬虫原理1. HTTP请求与响应过程2. 常用爬虫技术 二、P…...

搭建跨境电商电商独立站如何接入1688平台API接口|通过1688API接口采集商品通过链接搜索商品下单

接口设计|接口接入 对于mall项目中商品模块的接口设计&#xff0c;大家可以参考项目的Swagger接口文档&#xff0c;以Pms开头的接口就是商品模块对应的接口。 参数说明 通用参数说明 参数不要乱传&#xff0c;否则不管成功失败都会扣费url说明……d.cn/平台/API类型/ 平台&…...

【GlobalMapper精品教程】073:像素到点(Pixels-to-Points)从无人机图像轻松生成点云

文章目录 一、工具介绍二、生成点云三、生成正射四、生成3D模型五、注意事项一、工具介绍 Global Mapper v19引入的新的像素到点工具使用摄影测量原理,从重叠图像生成高密度点云、正射影像及三维模型。它使LiDAR模块成为已经功能很强大的的必备Global Mapper扩展功能。 打开…...

论文复现1:Mobilealoha

abstract:从人类演示中进行的模仿学习在机器人技术中表现出了令人印象深刻的表现。然而,大多数结果都集中在桌面操作上,缺乏一般有用任务所需的移动性和灵活性。在这项工作中,我们开发了一种用于模仿双手且需要全身控制的移动操纵任务的系统。我们首先推出 Mobile ALOHA,这…...

pycharm复习

目录 1.基础语法 2.判断语句 3.while循环 4.函数 5.数据容器 1.基础语法 1.字面量 2.注释&#xff1a; 单行注释# 多行注释" " " " " " 3.变量&#xff1a; 变量名 变量值 print&#xff1a;输出多个结果&#x…...

React hook之useRef

React useRef 详解 useRef 是 React 提供的一个 Hook&#xff0c;用于在函数组件中创建可变的引用对象。它在 React 开发中有多种重要用途&#xff0c;下面我将全面详细地介绍它的特性和用法。 基本概念 1. 创建 ref const refContainer useRef(initialValue);initialValu…...

shell脚本--常见案例

1、自动备份文件或目录 2、批量重命名文件 3、查找并删除指定名称的文件&#xff1a; 4、批量删除文件 5、查找并替换文件内容 6、批量创建文件 7、创建文件夹并移动文件 8、在文件夹中查找文件...

【android bluetooth 框架分析 04】【bt-framework 层详解 1】【BluetoothProperties介绍】

1. BluetoothProperties介绍 libsysprop/srcs/android/sysprop/BluetoothProperties.sysprop BluetoothProperties.sysprop 是 Android AOSP 中的一种 系统属性定义文件&#xff08;System Property Definition File&#xff09;&#xff0c;用于声明和管理 Bluetooth 模块相…...

Matlab | matlab常用命令总结

常用命令 一、 基础操作与环境二、 矩阵与数组操作(核心)三、 绘图与可视化四、 编程与控制流五、 符号计算 (Symbolic Math Toolbox)六、 文件与数据 I/O七、 常用函数类别重要提示这是一份 MATLAB 常用命令和功能的总结,涵盖了基础操作、矩阵运算、绘图、编程和文件处理等…...

处理vxe-table 表尾数据是单独一个接口,表格tableData数据更新后,需要点击两下,表尾才是正确的

修改bug思路&#xff1a; 分别把 tabledata 和 表尾相关数据 console.log() 发现 更新数据先后顺序不对 settimeout延迟查询表格接口 ——测试可行 升级↑&#xff1a;async await 等接口返回后再开始下一个接口查询 ________________________________________________________…...

RabbitMQ入门4.1.0版本(基于java、SpringBoot操作)

RabbitMQ 一、RabbitMQ概述 RabbitMQ RabbitMQ最初由LShift和CohesiveFT于2007年开发&#xff0c;后来由Pivotal Software Inc.&#xff08;现为VMware子公司&#xff09;接管。RabbitMQ 是一个开源的消息代理和队列服务器&#xff0c;用 Erlang 语言编写。广泛应用于各种分布…...

Linux部署私有文件管理系统MinIO

最近需要用到一个文件管理服务&#xff0c;但是又不想花钱&#xff0c;所以就想着自己搭建一个&#xff0c;刚好我们用的一个开源框架已经集成了MinIO&#xff0c;所以就选了这个 我这边对文件服务性能要求不是太高&#xff0c;单机版就可以 安装非常简单&#xff0c;几个命令就…...

渗透实战PortSwigger靶场:lab13存储型DOM XSS详解

进来是需要留言的&#xff0c;先用做简单的 html 标签测试 发现面的</h1>不见了 数据包中找到了一个loadCommentsWithVulnerableEscapeHtml.js 他是把用户输入的<>进行 html 编码&#xff0c;输入的<>当成字符串处理回显到页面中&#xff0c;看来只是把用户输…...

【Veristand】Veristand环境安装教程-Linux RT / Windows

首先声明&#xff0c;此教程是针对Simulink编译模型并导入Veristand中编写的&#xff0c;同时需要注意的是老用户编译可能用的是Veristand Model Framework&#xff0c;那个是历史版本&#xff0c;且NI不会再维护&#xff0c;新版本编译支持为VeriStand Model Generation Suppo…...

echarts使用graphic强行给图增加一个边框(边框根据自己的图形大小设置)- 适用于无法使用dom的样式

pdf-lib https://blog.csdn.net/Shi_haoliu/article/details/148157624?spm1001.2014.3001.5501 为了完成在pdf中导出echarts图&#xff0c;如果边框加在dom上面&#xff0c;pdf-lib导出svg的时候并不会导出边框&#xff0c;所以只能在echarts图上面加边框 grid的边框是在图里…...