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 中,vector 是一个非常重要的容器,它提供了动态数组的功能。在本篇博客中,我们将尝试模拟实现…...
UE4 方块排序动画
【动画效果】 入动画: 出动画: 【分析】 入动画:方块动画排序方式为Z字形,堆砌方向为X和Y轴向 出动画:方块动画排序方式为随机 【关键蓝图】 1.构建方块砌体 2.入/出动画...
网络与并发编程(一)
并发编程介绍_串行_并行_并发的区别 串行、并行与并发的区别 串行(serial):一个CPU上,按顺序完成多个任务并行(parallelism):指的是任务数小于等于cpu核数,即任务真的是一起执行的并发(concurrency):一个CPU采用时间…...
超详细工具Navicat安装教程
Navicat是一款功能强大的数据库管理工具,可用于管理多种类型的数据库,包括MySQL、MariaDB、SQL Server、SQLite、Oracle和PostgreSQL等。以下是Navicat工具的一些主要特点和功能: 一.功能介绍 跨平台支持 多种数据库支持 直观的用户界面 数据…...
RN在android/ios手机剪切图片的操作
之前写过一个React Native调用摄像头画面及拍照和保存图片到相册全流程但是这个仅限于调用摄像头拍照并保存图片,今天再写一个版本的操作,这个博客目前实现的有三点操作: 调用摄像头拍照对照片进行剪切从相册选取图片 功能上面来说有两点: 点击按钮可以对摄像头进行拍照,拍完照…...
C语言 | Leetcode C语言题解之第6题Z字形变换
题目: 题解: 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 回调函数的两种使用方法
对回调(callback)函数的一点粗陋理解,在我小时候,隔壁村有家月饼小作坊(只在中秋那段时间手工制作一些月饼出售,后来好像不做了),做出的月饼是那种很传统很经典的款式,里…...
医院云HIS系统源码,二级医院、专科医院his系统源码,经扩展后能够应用于医联体/医共体
基于云计算技术的B/S架构的HIS系统,为医疗机构提供标准化的、信息化的、可共享的医疗信息管理系统,实现医患事务管理和临床诊疗管理等标准医疗管理信息系统的功能。 系统利用云计算平台的技术优势,建立统一的云HIS、云病历、云LIS࿰…...
NineData云原生智能数据管理平台新功能发布|2024年3月版
数据库 DevOps - 大功能升级 SQL 开发早期主要提供 SQL 窗口(IDE)功能,在产品经过将近两年时间的打磨,新增了大量的企业级功能,已经服务了上万开发者,覆盖了数据库设计、开发、测试、变更等生命周期的功能…...
java Web 疫苗预约管理系统用eclipse定制开发mysql数据库BS模式java编程jdbc
一、源码特点 JSP 疫苗预约管理系统是一套完善的web设计系统,对理解JSP java 编程开发语言有帮助,系统具有完整的源代码和数据库,系统主要采用B/S模式开发。开发环境为TOMCAT7.0,eclipse开发,数据库为Mysql5.0,使…...
Qt5.14.2 揭秘Qt日志神器高效诊断程序潜在隐疾
对程序员而言,代码中的bug往往如同无影无踪的隐疾,影响着程序的健康运行。而及时有效的诊断手段则是治疗这些隐疾的良药。今天,我们将一窥Qt日志框架QLoggingCategory的神奇功效,探究它如何为你的Qt应用程序构筑坚实的诊断防火墙。…...
Mac上设置环境变量PATH
一、配置文件有哪些 在Mac系统中,环境变量的配置文件主要包括以下几个: 文件名称描述/etc/paths系统级别的配置文件,系统启动时会加载它。/etc/profile系统级别的配置文件,所有用户登录时都会读取该文件。~/.bash_profile用户级别…...
Redis 全景图(1)--- 关于 Redis 的6大模块
这是我第一次尝试以长文的形式写一篇 Redis 的总结文章。这篇文章我想写很久了,只是一直碍于我对 Redis 的掌握没有那么的好,因此迟迟未动笔。这几天,我一直在看各种不同类型的 Redis 文章,通过阅读这些文章,引发了我对…...
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;删除空数据库(如果有表会报错) drop database myhive;…...
Python爬虫详解:原理、常用库与实战案例
前言 前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家:https://www.captainbed.cn/z ChatGPT体验地址 文章目录 前言引言:一、爬虫原理1. HTTP请求与响应过程2. 常用爬虫技术 二、P…...
搭建跨境电商电商独立站如何接入1688平台API接口|通过1688API接口采集商品通过链接搜索商品下单
接口设计|接口接入 对于mall项目中商品模块的接口设计,大家可以参考项目的Swagger接口文档,以Pms开头的接口就是商品模块对应的接口。 参数说明 通用参数说明 参数不要乱传,否则不管成功失败都会扣费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.注释: 单行注释# 多行注释" " " " " " 3.变量: 变量名 变量值 print:输出多个结果&#x…...
(LeetCode 每日一题) 3442. 奇偶频次间的最大差值 I (哈希、字符串)
题目:3442. 奇偶频次间的最大差值 I 思路 :哈希,时间复杂度0(n)。 用哈希表来记录每个字符串中字符的分布情况,哈希表这里用数组即可实现。 C版本: class Solution { public:int maxDifference(string s) {int a[26]…...
【kafka】Golang实现分布式Masscan任务调度系统
要求: 输出两个程序,一个命令行程序(命令行参数用flag)和一个服务端程序。 命令行程序支持通过命令行参数配置下发IP或IP段、端口、扫描带宽,然后将消息推送到kafka里面。 服务端程序: 从kafka消费者接收…...
docker详细操作--未完待续
docker介绍 docker官网: Docker:加速容器应用程序开发 harbor官网:Harbor - Harbor 中文 使用docker加速器: Docker镜像极速下载服务 - 毫秒镜像 是什么 Docker 是一种开源的容器化平台,用于将应用程序及其依赖项(如库、运行时环…...
突破不可导策略的训练难题:零阶优化与强化学习的深度嵌合
强化学习(Reinforcement Learning, RL)是工业领域智能控制的重要方法。它的基本原理是将最优控制问题建模为马尔可夫决策过程,然后使用强化学习的Actor-Critic机制(中文译作“知行互动”机制),逐步迭代求解…...
智能在线客服平台:数字化时代企业连接用户的 AI 中枢
随着互联网技术的飞速发展,消费者期望能够随时随地与企业进行交流。在线客服平台作为连接企业与客户的重要桥梁,不仅优化了客户体验,还提升了企业的服务效率和市场竞争力。本文将探讨在线客服平台的重要性、技术进展、实际应用,并…...
【Zephyr 系列 10】实战项目:打造一个蓝牙传感器终端 + 网关系统(完整架构与全栈实现)
🧠关键词:Zephyr、BLE、终端、网关、广播、连接、传感器、数据采集、低功耗、系统集成 📌目标读者:希望基于 Zephyr 构建 BLE 系统架构、实现终端与网关协作、具备产品交付能力的开发者 📊篇幅字数:约 5200 字 ✨ 项目总览 在物联网实际项目中,**“终端 + 网关”**是…...
大学生职业发展与就业创业指导教学评价
这里是引用 作为软工2203/2204班的学生,我们非常感谢您在《大学生职业发展与就业创业指导》课程中的悉心教导。这门课程对我们即将面临实习和就业的工科学生来说至关重要,而您认真负责的教学态度,让课程的每一部分都充满了实用价值。 尤其让我…...
【Oracle】分区表
个人主页:Guiat 归属专栏:Oracle 文章目录 1. 分区表基础概述1.1 分区表的概念与优势1.2 分区类型概览1.3 分区表的工作原理 2. 范围分区 (RANGE Partitioning)2.1 基础范围分区2.1.1 按日期范围分区2.1.2 按数值范围分区 2.2 间隔分区 (INTERVAL Partit…...
JS手写代码篇----使用Promise封装AJAX请求
15、使用Promise封装AJAX请求 promise就有reject和resolve了,就不必写成功和失败的回调函数了 const BASEURL ./手写ajax/test.jsonfunction promiseAjax() {return new Promise((resolve, reject) > {const xhr new XMLHttpRequest();xhr.open("get&quo…...
uniapp手机号一键登录保姆级教程(包含前端和后端)
目录 前置条件创建uniapp项目并关联uniClound云空间开启一键登录模块并开通一键登录服务编写云函数并上传部署获取手机号流程(第一种) 前端直接调用云函数获取手机号(第三种)后台调用云函数获取手机号 错误码常见问题 前置条件 手机安装有sim卡手机开启…...
